From 0e10902ad7584277ac966367efc712b183784532 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 24 Jul 2014 16:16:53 +0200 Subject: mpi: Extend the internal mpi_get_buffer. * mpi/mpicoder.c (do_get_buffer): Add arg EXTRAALLOC. (_gcry_mpi_get_buffer_extra): New. --- mpi/mpicoder.c | 49 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) (limited to 'mpi/mpicoder.c') 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); } -- cgit v1.2.1