summaryrefslogtreecommitdiff
path: root/mpi
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2014-07-24 16:16:53 +0200
committerWerner Koch <wk@gnupg.org>2014-07-25 08:13:56 +0200
commit0e10902ad7584277ac966367efc712b183784532 (patch)
tree5f560d09e507254df5b556758f845cf536408939 /mpi
parent4e0bf1b9190ce08fb23eb3ae0c3be58954ff36ab (diff)
downloadlibgcrypt-0e10902ad7584277ac966367efc712b183784532.tar.gz
mpi: Extend the internal mpi_get_buffer.
* mpi/mpicoder.c (do_get_buffer): Add arg EXTRAALLOC. (_gcry_mpi_get_buffer_extra): New.
Diffstat (limited to 'mpi')
-rw-r--r--mpi/mpicoder.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/mpi/mpicoder.c b/mpi/mpicoder.c
index 58a42403..896dda14 100644
--- a/mpi/mpicoder.c
+++ b/mpi/mpicoder.c
@@ -1,7 +1,7 @@
/* 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
+ * Copyright (C) 2013, 2014 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -181,19 +181,27 @@ mpi_fromstr (gcry_mpi_t val, const char *str)
returned value is stored as little endian and right padded with
zeroes so that the returned buffer has at least FILL_LE bytes.
+ If EXTRAALLOC > 0 the returned buffer has these number of bytes
+ extra allocated at the end; if EXTRAALLOC < 0 the returned buffer
+ has the absolute value of EXTRAALLOC allocated at the begin of the
+ buffer (the are not initialized) and the MPI is stored right after
+ this. This feature is useful to allow the caller to prefix the
+ returned value. EXTRAALLOC is _not_ included in the value stored
+ at NBYTES.
+
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,
+do_get_buffer (gcry_mpi_t a, unsigned int fill_le, int extraalloc,
unsigned int *nbytes, int *sign, int force_secure)
{
- unsigned char *p, *buffer;
+ unsigned char *p, *buffer, *retbuffer;
unsigned int length, tmp;
mpi_limb_t alimb;
int i;
- size_t n;
+ size_t n, n2;
if (sign)
*sign = a->sign;
@@ -202,10 +210,20 @@ do_get_buffer (gcry_mpi_t a, unsigned int fill_le,
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)
+ if (extraalloc < 0)
+ n2 = n + -extraalloc;
+ else
+ n2 = n + extraalloc;
+
+ retbuffer = (force_secure || mpi_is_secure(a))? xtrymalloc_secure (n2)
+ : xtrymalloc (n2);
+ if (!retbuffer)
return NULL;
+ if (extraalloc < 0)
+ buffer = retbuffer + -extraalloc;
+ else
+ buffer = retbuffer;
+ p = buffer;
for (i=a->nlimbs-1; i >= 0; i--)
{
@@ -244,7 +262,7 @@ do_get_buffer (gcry_mpi_t a, unsigned int fill_le,
*p++ = 0;
*nbytes = length;
- return buffer;
+ return retbuffer;
}
/* This is sub-optimal but we need to do the shift operation because
@@ -252,8 +270,8 @@ do_get_buffer (gcry_mpi_t a, unsigned int fill_le,
for (p=buffer; *nbytes && !*p; p++, --*nbytes)
;
if (p != buffer)
- memmove (buffer,p, *nbytes);
- return buffer;
+ memmove (buffer, p, *nbytes);
+ return retbuffer;
}
@@ -261,14 +279,21 @@ 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);
+ return do_get_buffer (a, fill_le, 0, r_nbytes, sign, 0);
+}
+
+byte *
+_gcry_mpi_get_buffer_extra (gcry_mpi_t a, unsigned int fill_le, int extraalloc,
+ unsigned int *r_nbytes, int *sign)
+{
+ return do_get_buffer (a, fill_le, extraalloc, 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);
+ return do_get_buffer (a, fill_le, 0, r_nbytes, sign, 1);
}