/* mpicoder.c  -  Coder for the external representation of MPIs
 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
 *               2008 Free Software Foundation, Inc.
 * Copyright (C) 2013 g10 Code GmbH
 *
 * This file is part of Libgcrypt.
 *
 * Libgcrypt is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * Libgcrypt is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include <config.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "mpi-internal.h"
#include "g10lib.h"

#define MAX_EXTERN_MPI_BITS 16384

/* Helper used to scan PGP style MPIs.  Returns NULL on failure. */
static gcry_mpi_t
mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
                      int secure)
{
  int i, j;
  unsigned int nbits, nbytes, nlimbs, nread=0;
  mpi_limb_t a;
  gcry_mpi_t val = MPI_NULL;

  if ( *ret_nread < 2 )
    goto leave;
  nbits = buffer[0] << 8 | buffer[1];
  if ( nbits > MAX_EXTERN_MPI_BITS )
    {
/*       log_debug ("mpi too large (%u bits)\n", nbits); */
      goto leave;
    }
  buffer += 2;
  nread = 2;

  nbytes = (nbits+7) / 8;
  nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
  val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc (nlimbs);
  i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
  i %= BYTES_PER_MPI_LIMB;
  j= val->nlimbs = nlimbs;
  val->sign = 0;
  for ( ; j > 0; j-- )
    {
      a = 0;
      for (; i < BYTES_PER_MPI_LIMB; i++ )
        {
          if ( ++nread > *ret_nread )
            {
/*               log_debug ("mpi larger than buffer"); */
              mpi_free (val);
              val = NULL;
              goto leave;
            }
          a <<= 8;
          a |= *buffer++;
	}
      i = 0;
      val->d[j-1] = a;
    }

 leave:
  *ret_nread = nread;
  return val;
}


/****************
 * Fill the mpi VAL from the hex string in STR.
 */
static int
mpi_fromstr (gcry_mpi_t val, const char *str)
{
  int sign = 0;
  int prepend_zero = 0;
  int i, j, c, c1, c2;
  unsigned int nbits, nbytes, nlimbs;
  mpi_limb_t a;

  if ( *str == '-' )
    {
      sign = 1;
      str++;
    }

  /* Skip optional hex prefix.  */
  if ( *str == '0' && str[1] == 'x' )
    str += 2;

  nbits = 4 * strlen (str);
  if ((nbits % 8))
    prepend_zero = 1;

  nbytes = (nbits+7) / 8;
  nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;

  if ( val->alloced < nlimbs )
    mpi_resize (val, nlimbs);

  i = BYTES_PER_MPI_LIMB - (nbytes % BYTES_PER_MPI_LIMB);
  i %= BYTES_PER_MPI_LIMB;
  j = val->nlimbs = nlimbs;
  val->sign = sign;
  for (; j > 0; j--)
    {
      a = 0;
      for (; i < BYTES_PER_MPI_LIMB; i++)
        {
          if (prepend_zero)
            {
              c1 = '0';
              prepend_zero = 0;
	    }
          else
            c1 = *str++;

          if (!c1)
            {
              mpi_clear (val);
              return 1;  /* Error.  */
	    }
          c2 = *str++;
          if (!c2)
            {
              mpi_clear (val);
              return 1;  /* Error.  */
	    }
          if ( c1 >= '0' && c1 <= '9' )
            c = c1 - '0';
          else if ( c1 >= 'a' && c1 <= 'f' )
            c = c1 - 'a' + 10;
          else if ( c1 >= 'A' && c1 <= 'F' )
            c = c1 - 'A' + 10;
          else
            {
              mpi_clear (val);
              return 1;  /* Error.  */
	    }
          c <<= 4;
          if ( c2 >= '0' && c2 <= '9' )
            c |= c2 - '0';
          else if( c2 >= 'a' && c2 <= 'f' )
            c |= c2 - 'a' + 10;
          else if( c2 >= 'A' && c2 <= 'F' )
            c |= c2 - 'A' + 10;
          else
            {
              mpi_clear(val);
              return 1;  /* Error. */
	    }
          a <<= 8;
          a |= c;
	}
      i = 0;
      val->d[j-1] = a;
    }

  return 0;  /* Okay.  */
}


/* Return an allocated buffer with the MPI (msb first).  NBYTES
   receives the length of this buffer.  If FILL_LE is not 0, the
   returned value is stored as little endian and right padded with
   zeroes so that the returned buffer has at least FILL_LE bytes.

   Caller must free the return string.  This function returns an
   allocated buffer with NBYTES set to zero if the value of A is zero.
   If sign is not NULL, it will be set to the sign of the A.  On error
   NULL is returned and ERRNO set appropriately.  */
static unsigned char *
do_get_buffer (gcry_mpi_t a, unsigned int fill_le,
               unsigned int *nbytes, int *sign, int force_secure)
{
  unsigned char *p, *buffer;
  unsigned int length, tmp;
  mpi_limb_t alimb;
  int i;
  size_t n;

  if (sign)
    *sign = a->sign;

  *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
  n = *nbytes? *nbytes:1; /* Allocate at least one byte.  */
  if (n < fill_le)
    n = fill_le;
  p = buffer = (force_secure || mpi_is_secure(a))? xtrymalloc_secure (n)
						 : xtrymalloc (n);
  if (!buffer)
    return NULL;

  for (i=a->nlimbs-1; i >= 0; i--)
    {
      alimb = a->d[i];
#if BYTES_PER_MPI_LIMB == 4
      *p++ = alimb >> 24;
      *p++ = alimb >> 16;
      *p++ = alimb >>  8;
      *p++ = alimb	  ;
#elif BYTES_PER_MPI_LIMB == 8
      *p++ = alimb >> 56;
      *p++ = alimb >> 48;
      *p++ = alimb >> 40;
      *p++ = alimb >> 32;
      *p++ = alimb >> 24;
      *p++ = alimb >> 16;
      *p++ = alimb >>  8;
      *p++ = alimb	  ;
#else
#     error please implement for this limb size.
#endif
    }

  if (fill_le)
    {
      length = *nbytes;
      /* Reverse buffer and pad with zeroes.  */
      for (i=0; i < length/2; i++)
        {
          tmp = buffer[i];
          buffer[i] = buffer[length-1-i];
          buffer[length-1-i] = tmp;
        }
      /* Pad with zeroes.  */
      for (p = buffer + length; length < fill_le; length++)
        *p++ = 0;
      *nbytes = length;

      return buffer;
    }

  /* This is sub-optimal but we need to do the shift operation because
     the caller has to free the returned buffer.  */
  for (p=buffer; *nbytes && !*p; p++, --*nbytes)
    ;
  if (p != buffer)
    memmove (buffer,p, *nbytes);
  return buffer;
}


byte *
_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int fill_le,
                      unsigned int *r_nbytes, int *sign)
{
  return do_get_buffer (a, fill_le, r_nbytes, sign, 0);
}

byte *
_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned int fill_le,
                             unsigned int *r_nbytes, int *sign)
{
  return do_get_buffer (a, fill_le, r_nbytes, sign, 1);
}


/*
 * Use the NBYTES at BUFFER_ARG to update A.  Set the sign of a to
 * SIGN.
 */
void
_gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
                      unsigned int nbytes, int sign)
{
  const unsigned char *buffer = (const unsigned char*)buffer_arg;
  const unsigned char *p;
  mpi_limb_t alimb;
  int nlimbs;
  int i;

  if (mpi_is_immutable (a))
    {
      mpi_immutable_failed ();
      return;
    }

  nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
  RESIZE_IF_NEEDED(a, nlimbs);
  a->sign = sign;

  for (i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; )
    {
#if BYTES_PER_MPI_LIMB == 4
      alimb  = *p--	    ;
      alimb |= *p-- <<  8 ;
      alimb |= *p-- << 16 ;
      alimb |= *p-- << 24 ;
#elif BYTES_PER_MPI_LIMB == 8
      alimb  = (mpi_limb_t)*p--	;
      alimb |= (mpi_limb_t)*p-- <<  8 ;
      alimb |= (mpi_limb_t)*p-- << 16 ;
      alimb |= (mpi_limb_t)*p-- << 24 ;
      alimb |= (mpi_limb_t)*p-- << 32 ;
      alimb |= (mpi_limb_t)*p-- << 40 ;
      alimb |= (mpi_limb_t)*p-- << 48 ;
      alimb |= (mpi_limb_t)*p-- << 56 ;
#else
#       error please implement for this limb size.
#endif
      a->d[i++] = alimb;
    }
  if ( p >= buffer )
    {
#if BYTES_PER_MPI_LIMB == 4
      alimb  = *p--;
      if (p >= buffer)
        alimb |= *p-- <<  8;
      if (p >= buffer)
        alimb |= *p-- << 16;
      if (p >= buffer)
        alimb |= *p-- << 24;
#elif BYTES_PER_MPI_LIMB == 8
      alimb  = (mpi_limb_t)*p--;
      if (p >= buffer)
        alimb |= (mpi_limb_t)*p-- << 8;
      if (p >= buffer)
        alimb |= (mpi_limb_t)*p-- << 16;
      if (p >= buffer)
        alimb |= (mpi_limb_t)*p-- << 24;
      if (p >= buffer)
        alimb |= (mpi_limb_t)*p-- << 32;
      if (p >= buffer)
        alimb |= (mpi_limb_t)*p-- << 40;
      if (p >= buffer)
        alimb |= (mpi_limb_t)*p-- << 48;
      if (p >= buffer)
        alimb |= (mpi_limb_t)*p-- << 56;
#else
#     error please implement for this limb size.
#endif
      a->d[i++] = alimb;
    }
  a->nlimbs = i;
  gcry_assert (i == nlimbs);
}


static void
onecompl (gcry_mpi_t a)
{
  mpi_ptr_t ap;
  mpi_size_t n;
  unsigned int i;
  unsigned int nbits = mpi_get_nbits (a);

  if (mpi_is_immutable (a))
    {
      mpi_immutable_failed ();
      return;
    }

  mpi_normalize (a);
  ap = a->d;
  n = a->nlimbs;

  for( i = 0; i < n; i++ )
    ap[i] ^= (mpi_limb_t)(-1);

  a->sign = 0;
  mpi_clear_highbit (a, nbits-1);
}


/* Perform a two's complement operation on buffer P of size N bytes.  */
static void
twocompl (unsigned char *p, unsigned int n)
{
  int i;

  for (i=n-1; i >= 0 && !p[i]; i--)
    ;
  if (i >= 0)
    {
      if ((p[i] & 0x01))
        p[i] = (((p[i] ^ 0xfe) | 0x01) & 0xff);
      else if ((p[i] & 0x02))
        p[i] = (((p[i] ^ 0xfc) | 0x02) & 0xfe);
      else if ((p[i] & 0x04))
        p[i] = (((p[i] ^ 0xf8) | 0x04) & 0xfc);
      else if ((p[i] & 0x08))
        p[i] = (((p[i] ^ 0xf0) | 0x08) & 0xf8);
      else if ((p[i] & 0x10))
        p[i] = (((p[i] ^ 0xe0) | 0x10) & 0xf0);
      else if ((p[i] & 0x20))
        p[i] = (((p[i] ^ 0xc0) | 0x20) & 0xe0);
      else if ((p[i] & 0x40))
        p[i] = (((p[i] ^ 0x80) | 0x40) & 0xc0);
      else
        p[i] = 0x80;

      for (i--; i >= 0; i--)
        p[i] ^= 0xff;
    }
}


/* Convert the external representation of an integer stored in BUFFER
   with a length of BUFLEN into a newly create MPI returned in
   RET_MPI.  If NBYTES is not NULL, it will receive the number of
   bytes actually scanned after a successful operation.  */
gcry_err_code_t
_gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
                const void *buffer_arg, size_t buflen, size_t *nscanned)
{
  const unsigned char *buffer = (const unsigned char*)buffer_arg;
  struct gcry_mpi *a = NULL;
  unsigned int len;
  int secure = (buffer && _gcry_is_secure (buffer));

  if (format == GCRYMPI_FMT_SSH)
    len = 0;
  else
    len = buflen;

  if (format == GCRYMPI_FMT_STD)
    {
      const unsigned char *s = buffer;

      a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
                                    /BYTES_PER_MPI_LIMB)
                : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
      if (len)
        {
          _gcry_mpi_set_buffer (a, s, len, 0);
          a->sign = !!(*s & 0x80);
          if (a->sign)
            {
              onecompl (a);
              mpi_add_ui (a, a, 1);
              a->sign = 1;
	    }
	}
      if (ret_mpi)
        {
          mpi_normalize ( a );
          *ret_mpi = a;
	}
      else
        mpi_free(a);
      if (nscanned)
        *nscanned = len;
      return 0;
    }
  else if (format == GCRYMPI_FMT_USG)
    {
      a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
                                    /BYTES_PER_MPI_LIMB)
                : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);

      if (len)
        _gcry_mpi_set_buffer (a, buffer, len, 0);
      if (ret_mpi)
        {
          mpi_normalize ( a );
          *ret_mpi = a;
	}
      else
        mpi_free(a);
      if (nscanned)
        *nscanned = len;
      return 0;
    }
  else if (format == GCRYMPI_FMT_PGP)
    {
      a = mpi_read_from_buffer (buffer, &len, secure);
      if (nscanned)
        *nscanned = len;
      if (ret_mpi && a)
        {
          mpi_normalize (a);
          *ret_mpi = a;
	}
      else if (a)
        {
          mpi_free(a);
          a = NULL;
        }
      return a? 0 : GPG_ERR_INV_OBJ;
    }
  else if (format == GCRYMPI_FMT_SSH)
    {
      const unsigned char *s = buffer;
      size_t n;

      /* This test is not strictly necessary and an assert (!len)
         would be sufficient.  We keep this test in case we later
         allow the BUFLEN argument to act as a sanitiy check.  Same
         below. */
      if (len && len < 4)
        return GPG_ERR_TOO_SHORT;

      n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
      s += 4;
      if (len)
        len -= 4;
      if (len && n > len)
        return GPG_ERR_TOO_LARGE;

      a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
                                    /BYTES_PER_MPI_LIMB)
                : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
      if (n)
        {
          _gcry_mpi_set_buffer( a, s, n, 0 );
          a->sign = !!(*s & 0x80);
          if (a->sign)
            {
              onecompl (a);
              mpi_add_ui (a, a, 1);
              a->sign = 1;
	    }
	}
      if (nscanned)
        *nscanned = n+4;
      if (ret_mpi)
        {
          mpi_normalize ( a );
          *ret_mpi = a;
        }
      else
        mpi_free(a);
      return 0;
    }
  else if (format == GCRYMPI_FMT_HEX)
    {
      /* We can only handle C strings for now.  */
      if (buflen)
        return GPG_ERR_INV_ARG;

      a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
      if (mpi_fromstr (a, (const char *)buffer))
        {
          mpi_free (a);
          return GPG_ERR_INV_OBJ;
        }
      if (ret_mpi)
        {
          mpi_normalize ( a );
          *ret_mpi = a;
	}
      else
        mpi_free(a);
      if (nscanned)
        *nscanned = strlen ((const char*)buffer);
      return 0;
    }
  else
    return GPG_ERR_INV_ARG;
}


/* Convert the big integer A into the external representation
   described by FORMAT and store it in the provided BUFFER which has
   been allocated by the user with a size of BUFLEN bytes.  NWRITTEN
   receives the actual length of the external representation unless it
   has been passed as NULL.  BUFFER may be NULL to query the required
   length.  */
gcry_err_code_t
_gcry_mpi_print (enum gcry_mpi_format format,
                 unsigned char *buffer, size_t buflen,
                 size_t *nwritten, struct gcry_mpi *a)
{
  unsigned int nbits = mpi_get_nbits (a);
  size_t len;
  size_t dummy_nwritten;
  int negative;

  if (!nwritten)
    nwritten = &dummy_nwritten;

  /* Libgcrypt does no always care to set clear the sign if the value
     is 0.  For printing this is a bit of a surprise, in particular
     because if some of the formats don't support negative numbers but
     should be able to print a zero.  Thus we need this extra test
     for a negative number.  */
  if (a->sign && _gcry_mpi_cmp_ui (a, 0))
    negative = 1;
  else
    negative = 0;

  len = buflen;
  *nwritten = 0;
  if (format == GCRYMPI_FMT_STD)
    {
      unsigned char *tmp;
      int extra = 0;
      unsigned int n;

      tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
      if (!tmp)
        return gpg_err_code_from_syserror ();

      if (negative)
        {
          twocompl (tmp, n);
          if (!(*tmp & 0x80))
            {
              /* Need to extend the sign.  */
              n++;
              extra = 2;
            }
        }
      else if (n && (*tmp & 0x80))
        {
          /* Positive but the high bit of the returned buffer is set.
             Thus we need to print an extra leading 0x00 so that the
             output is interpreted as a positive number.  */
          n++;
          extra = 1;
	}

      if (buffer && n > len)
        {
          /* The provided buffer is too short. */
          xfree (tmp);
          return GPG_ERR_TOO_SHORT;
	}
      if (buffer)
        {
          unsigned char *s = buffer;

          if (extra == 1)
            *s++ = 0;
          else if (extra)
            *s++ = 0xff;
          memcpy (s, tmp, n-!!extra);
	}
      xfree (tmp);
      *nwritten = n;
      return 0;
    }
  else if (format == GCRYMPI_FMT_USG)
    {
      unsigned int n = (nbits + 7)/8;

      /* Note:  We ignore the sign for this format.  */
      /* FIXME: for performance reasons we should put this into
	 mpi_aprint because we can then use the buffer directly.  */

      if (buffer && n > len)
        return GPG_ERR_TOO_SHORT;
      if (buffer)
        {
          unsigned char *tmp;

          tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
          if (!tmp)
            return gpg_err_code_from_syserror ();
          memcpy (buffer, tmp, n);
          xfree (tmp);
	}
      *nwritten = n;
      return 0;
    }
  else if (format == GCRYMPI_FMT_PGP)
    {
      unsigned int n = (nbits + 7)/8;

      /* The PGP format can only handle unsigned integers.  */
      if (negative)
        return GPG_ERR_INV_ARG;

      if (buffer && n+2 > len)
        return GPG_ERR_TOO_SHORT;

      if (buffer)
        {
          unsigned char *tmp;
          unsigned char *s = buffer;

          s[0] = nbits >> 8;
          s[1] = nbits;

          tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
          if (!tmp)
            return gpg_err_code_from_syserror ();
          memcpy (s+2, tmp, n);
          xfree (tmp);
	}
      *nwritten = n+2;
      return 0;
    }
  else if (format == GCRYMPI_FMT_SSH)
    {
      unsigned char *tmp;
      int extra = 0;
      unsigned int n;

      tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
      if (!tmp)
        return gpg_err_code_from_syserror ();

      if (negative)
        {
          twocompl (tmp, n);
          if (!(*tmp & 0x80))
            {
              /* Need to extend the sign.  */
              n++;
              extra = 2;
            }
        }
      else if (n && (*tmp & 0x80))
        {
          n++;
          extra=1;
	}

      if (buffer && n+4 > len)
        {
          xfree(tmp);
          return GPG_ERR_TOO_SHORT;
	}

      if (buffer)
        {
          unsigned char *s = buffer;

          *s++ = n >> 24;
          *s++ = n >> 16;
          *s++ = n >> 8;
          *s++ = n;
          if (extra == 1)
            *s++ = 0;
          else if (extra)
            *s++ = 0xff;
          memcpy (s, tmp, n-!!extra);
	}
      xfree (tmp);
      *nwritten = 4+n;
      return 0;
    }
  else if (format == GCRYMPI_FMT_HEX)
    {
      unsigned char *tmp;
      int i;
      int extra = 0;
      unsigned int n = 0;

      tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
      if (!tmp)
        return gpg_err_code_from_syserror ();
      if (!n || (*tmp & 0x80))
        extra = 2;

      if (buffer && 2*n + extra + negative + 1 > len)
        {
          xfree(tmp);
          return GPG_ERR_TOO_SHORT;
	}
      if (buffer)
        {
          unsigned char *s = buffer;

          if (negative)
            *s++ = '-';
          if (extra)
            {
              *s++ = '0';
              *s++ = '0';
	    }

          for (i=0; i < n; i++)
            {
              unsigned int c = tmp[i];

              *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ;
              c &= 15;
              *s++ = c < 10? '0'+c : 'A'+c-10 ;
	    }
          *s++ = 0;
          *nwritten = s - buffer;
	}
      else
        {
          *nwritten = 2*n + extra + negative + 1;
	}
      xfree (tmp);
      return 0;
    }
  else
    return GPG_ERR_INV_ARG;
}


/*
 * Like gcry_mpi_print but this function allocates the buffer itself.
 * The caller has to supply the address of a pointer.  NWRITTEN may be
 * NULL.
 */
gcry_err_code_t
_gcry_mpi_aprint (enum gcry_mpi_format format,
                  unsigned char **buffer, size_t *nwritten,
                  struct gcry_mpi *a)
{
  size_t n;
  gcry_err_code_t rc;

  *buffer = NULL;
  rc = _gcry_mpi_print (format, NULL, 0, &n, a);
  if (rc)
    return rc;

  *buffer = mpi_is_secure(a) ? xtrymalloc_secure (n?n:1) : xtrymalloc (n?n:1);
  if (!*buffer)
    return gpg_err_code_from_syserror ();
  /* If the returned buffer will have a length of 0, we nevertheless
     allocated 1 byte (malloc needs it anyway) and store a 0.  */
  if (!n)
    **buffer = 0;
  rc = _gcry_mpi_print( format, *buffer, n, &n, a );
  if (rc)
    {
      xfree (*buffer);
      *buffer = NULL;
    }
  else if (nwritten)
    *nwritten = n;
  return rc;
}


/* Turn VALUE into an octet string and store it in an allocated buffer
   at R_FRAME or - if R_RAME is NULL - copy it into the caller
   provided buffer SPACE; either SPACE or R_FRAME may be used.  If
   SPACE if not NULL, the caller must provide a buffer of at least
   NBYTES.  If the resulting octet string is shorter than NBYTES pad
   it to the left with zeroes.  If VALUE does not fit into NBYTES
   return an error code.  */
gpg_err_code_t
_gcry_mpi_to_octet_string (unsigned char **r_frame, void *space,
                           gcry_mpi_t value, size_t nbytes)
{
  gpg_err_code_t rc;
  size_t nframe, noff, n;
  unsigned char *frame;

  if (!r_frame == !space)
    return GPG_ERR_INV_ARG;  /* Only one may be used.  */

  if (r_frame)
    *r_frame = NULL;

  rc = _gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nframe, value);
  if (rc)
    return rc;
  if (nframe > nbytes)
    return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES.  */

  noff = (nframe < nbytes)? nbytes - nframe : 0;
  n = nframe + noff;
  if (space)
    frame = space;
  else
    {
      frame = mpi_is_secure (value)? xtrymalloc_secure (n) : xtrymalloc (n);
      if (!frame)
        {
          rc = gpg_err_code_from_syserror ();
          return rc;
        }
    }
  if (noff)
    memset (frame, 0, noff);
  nframe += noff;
  rc = _gcry_mpi_print (GCRYMPI_FMT_USG, frame+noff, nframe-noff, NULL, value);
  if (rc)
    {
      xfree (frame);
      return rc;
    }

  if (r_frame)
    *r_frame = frame;
  return 0;
}
