diff options
author | Werner Koch <wk@gnupg.org> | 2008-12-04 16:24:23 +0000 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2008-12-04 16:24:23 +0000 |
commit | a51072bd6bf2c44bdd081d30c0fa1b8214e50471 (patch) | |
tree | b133fb9990aa85369040ba0f414aefb564a0f2c4 /mpi/mpicoder.c | |
parent | 390f32037538ac7c4b6c0a18581861f028bffabb (diff) | |
download | libgcrypt-a51072bd6bf2c44bdd081d30c0fa1b8214e50471.tar.gz |
Re-indent source4.
Diffstat (limited to 'mpi/mpicoder.c')
-rw-r--r-- | mpi/mpicoder.c | 876 |
1 files changed, 472 insertions, 404 deletions
diff --git a/mpi/mpicoder.c b/mpi/mpicoder.c index d8f860ce..ce20abc6 100644 --- a/mpi/mpicoder.c +++ b/mpi/mpicoder.c @@ -15,8 +15,7 @@ * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include <config.h> @@ -29,7 +28,7 @@ #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) @@ -86,74 +85,85 @@ mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread, * Make an mpi from a hex character string. */ static int -mpi_fromstr(gcry_mpi_t val, const char *str) +mpi_fromstr (gcry_mpi_t val, const char *str) { - int sign=0, prepend_zero=0, i, j, c, c1, c2; - unsigned nbits, nbytes, nlimbs; - mpi_limb_t a; + 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++; + if ( *str == '-' ) + { + sign = 1; + str++; } - /* skip optional hex prefix */ - if ( *str == '0' && str[1] == 'x' ) { - str += 2; - } + /* 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); - nbits = strlen(str)*4; - 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; + 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++; - gcry_assert (c1); - c2 = *str++; - gcry_assert (c2); - 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; + else + c1 = *str++; + + gcry_assert (c1); + c2 = *str++; + gcry_assert (c2); + 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; + 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; + a <<= 8; + a |= c; } - i = 0; - val->d[j-1] = a; + i = 0; + val->d[j-1] = a; } - - return 0; + + return 0; /* Okay. */ } @@ -204,447 +214,505 @@ _gcry_log_mpidump (const char *text, gcry_mpi_t a) } -/**************** - * Return an m_alloced buffer with the MPI (msb first). - * NBYTES receives the length of this buffer. Caller must free the - * return string (This function does return a 0 byte 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. - */ -static byte * -do_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign, int force_secure ) +/* Return an allocated buffer with the MPI (msb first). NBYTES + receives the length of this buffer. Caller must free the return + string. This function does return a 0 byte 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. */ +static unsigned char * +do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure) { - byte *p, *buffer; - 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 */ - p = buffer = force_secure || mpi_is_secure(a) ? gcry_xmalloc_secure(n) + unsigned char *p, *buffer; + 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. */ + p = buffer = force_secure || mpi_is_secure(a) ? gcry_xmalloc_secure(n) : gcry_xmalloc(n); - for(i=a->nlimbs-1; i >= 0; i-- ) { - alimb = a->d[i]; + 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 ; + *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 ; + *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. +# error please implement for this limb size. #endif } - /* This is sub-optimal but we need to do the shift operation - because the caller has to free the returned buffer */ - for(p=buffer; !*p && *nbytes; p++, --*nbytes ) - ; - if( p != buffer ) - memmove(buffer,p, *nbytes); - 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; !*p && *nbytes; p++, --*nbytes) + ; + if (p != buffer) + memmove (buffer,p, *nbytes); + return buffer; } byte * -_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign ) +_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign) { - return do_get_buffer( a, nbytes, sign, 0 ); + return do_get_buffer (a, nbytes, sign, 0); } byte * -_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign ) +_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned *nbytes, int *sign) { - return do_get_buffer( a, nbytes, sign, 1 ); + return do_get_buffer (a, nbytes, sign, 1); } -/**************** - * Use BUFFER to update MPI. + +/* + * 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 ) +_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 byte *p; - mpi_limb_t alimb; - int nlimbs; - int i; - - 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; ) { + const unsigned char *buffer = (const unsigned char*)buffer_arg; + const unsigned char *p; + mpi_limb_t alimb; + int nlimbs; + int i; + + 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 ; + 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 ; + 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. +# error please implement for this limb size. #endif - a->d[i++] = alimb; + a->d[i++] = alimb; } - if( p >= buffer ) { + 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 ; + 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 ; + 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. +# error please implement for this limb size. #endif - a->d[i++] = alimb; + a->d[i++] = alimb; } - a->nlimbs = i; - gcry_assert (i == nlimbs); + a->nlimbs = i; + gcry_assert (i == nlimbs); } - /* 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. */ + bytes actually scanned after a successful operation. */ gcry_error_t -gcry_mpi_scan( struct gcry_mpi **ret_mpi, enum gcry_mpi_format format, - const void *buffer_arg, size_t buflen, size_t *nscanned ) +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 byte *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 ) { /* not zero */ - a->sign = *s & 0x80; - if( a->sign ) { - /* FIXME: we have to convert from 2compl to magnitude format */ - mpi_free(a); - return gcry_error (GPG_ERR_INTERNAL); + 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) + { + a->sign = !!(*s & 0x80); + if (a->sign) + { + /* FIXME: we have to convert from 2compl to magnitude format */ + mpi_free (a); + return gcry_error (GPG_ERR_INTERNAL); } - else - _gcry_mpi_set_buffer( a, s, len, 0 ); + else + _gcry_mpi_set_buffer (a, s, len, 0); } - if( ret_mpi ) { - mpi_normalize ( a ); - *ret_mpi = a; + if (ret_mpi) + { + mpi_normalize ( a ); + *ret_mpi = a; } - else - mpi_free(a); - return gcry_error (GPG_ERR_NO_ERROR); + else + mpi_free(a); + return gcry_error (GPG_ERR_NO_ERROR); } - 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 ) /* not zero */ - _gcry_mpi_set_buffer( a, buffer, len, 0 ); - if( ret_mpi ) { - mpi_normalize ( a ); - *ret_mpi = a; + 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); - return gcry_error (GPG_ERR_NO_ERROR); + else + mpi_free(a); + 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 (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 - mpi_free(a); - return gcry_error (a ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ); + else + mpi_free(a); + return gcry_error (a ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ); } - else if( format == GCRYMPI_FMT_SSH ) { - const unsigned char *s = buffer; - size_t n; - - if( len && len < 4 ) - return gcry_error (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 gcry_error (GPG_ERR_TOO_LARGE); /* or should it be - too_short */ - - 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 ) { /* not zero */ - a->sign = *s & 0x80; - if( a->sign ) { - /* FIXME: we have to convert from 2compl to magnitude format */ - mpi_free(a); - return gcry_error (GPG_ERR_INTERNAL); + else if (format == GCRYMPI_FMT_SSH) + { + const unsigned char *s = buffer; + size_t n; + + if (len && len < 4) + return gcry_error (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 gcry_error (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) + { + a->sign = !!(*s & 0x80); + if (a->sign) + { + /* FIXME: we have to convert from 2compl to magnitude format */ + mpi_free(a); + return gcry_error (GPG_ERR_INTERNAL); } - else - _gcry_mpi_set_buffer( a, s, n, 0 ); + else + _gcry_mpi_set_buffer( a, s, n, 0 ); } - if( nscanned ) - *nscanned = n+4; - if( ret_mpi ) { + if (nscanned) + *nscanned = n+4; + if (ret_mpi) + { mpi_normalize ( a ); *ret_mpi = a; - } + } else - mpi_free(a); - return gcry_error (GPG_ERR_NO_ERROR); + mpi_free(a); + return 0; } - else if( format == GCRYMPI_FMT_HEX ) { - if( buflen ) - return gcry_error (GPG_ERR_INV_ARG); /* can only handle C - strings for now */ - a = secure? mpi_alloc_secure (0) : mpi_alloc(0); - if( mpi_fromstr ( a, (const char *)buffer ) ) - return gcry_error (GPG_ERR_INV_OBJ); - if( ret_mpi ) { - mpi_normalize ( a ); - *ret_mpi = a; + else if (format == GCRYMPI_FMT_HEX) + { + /* We can only handle C strings for now. */ + if (buflen) + return gcry_error (GPG_ERR_INV_ARG); + + a = secure? mpi_alloc_secure (0) : mpi_alloc(0); + if (mpi_fromstr (a, (const char *)buffer)) + return gcry_error (GPG_ERR_INV_OBJ); + if (ret_mpi) + { + mpi_normalize ( a ); + *ret_mpi = a; } - else - mpi_free(a); - return gcry_error (GPG_ERR_NO_ERROR); + else + mpi_free(a); + return 0; } - else - return gcry_error (GPG_ERR_INV_ARG); + else + return gcry_error (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.*/ + length. */ gcry_error_t -gcry_mpi_print( enum gcry_mpi_format format, +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; + unsigned int nbits = mpi_get_nbits (a); + size_t len; + size_t dummy_nwritten; + + if (!nwritten) + nwritten = &dummy_nwritten; - if (!nwritten) - nwritten = &dummy_nwritten; + len = buflen; + *nwritten = 0; + if (format == GCRYMPI_FMT_STD) + { + unsigned char *tmp; + int extra = 0; + unsigned int n; + + if (a->sign) + return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */ - len = buflen; - *nwritten = 0; - if( format == GCRYMPI_FMT_STD ) { - unsigned char *tmp; - int extra = 0; - unsigned int n; - - if( a->sign ) - return gcry_error (GPG_ERR_INTERNAL); /* can't handle it yet */ - - tmp = _gcry_mpi_get_buffer( a, &n, NULL ); - if( n && (*tmp & 0x80) ) { - n++; - extra=1; + tmp = _gcry_mpi_get_buffer (a, &n, NULL); + if (n && (*tmp & 0x80)) + { + n++; + extra=1; } - - if (buffer && n > len) { - /* The provided buffer is too short. */ - gcry_free (tmp); - return gcry_error (GPG_ERR_TOO_SHORT); + + if (buffer && n > len) + { + /* The provided buffer is too short. */ + gcry_free (tmp); + return gcry_error (GPG_ERR_TOO_SHORT); } - if( buffer ) { - unsigned char *s = buffer; - if( extra ) - *s++ = 0; + if (buffer) + { + unsigned char *s = buffer; - memcpy( s, tmp, n-extra ); + if (extra) + *s++ = 0; + memcpy (s, tmp, n-extra); } - gcry_free(tmp); - *nwritten = n; - return gcry_error (GPG_ERR_NO_ERROR); + gcry_free(tmp); + *nwritten = n; + return 0; } - else if( format == GCRYMPI_FMT_USG ) { - unsigned int n = (nbits + 7)/8; - - /* we ignore the sign for this format */ - /* FIXME: for performance reasons we should put this into - * mpi_aprint becuase we can then use the buffer directly */ - if (buffer && n > len) - return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */ - if( buffer ) { - unsigned char *tmp; - tmp = _gcry_mpi_get_buffer( a, &n, NULL ); - memcpy( buffer, tmp, n ); - gcry_free(tmp); + 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 gcry_error (GPG_ERR_TOO_SHORT); + if (buffer) + { + unsigned char *tmp; + + tmp = _gcry_mpi_get_buffer (a, &n, NULL); + memcpy (buffer, tmp, n); + gcry_free (tmp); } - *nwritten = n; - return gcry_error (GPG_ERR_NO_ERROR); + *nwritten = n; + return 0; } - else if( format == GCRYMPI_FMT_PGP ) { - unsigned int n = (nbits + 7)/8; - - if( a->sign ) - return gcry_error (GPG_ERR_INV_ARG); /* pgp format can only handle unsigned */ - - if (buffer && n+2 > len) - return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */ - if( buffer ) { - unsigned char *tmp; - unsigned char *s = buffer; - s[0] = nbits >> 8; - s[1] = nbits; - - tmp = _gcry_mpi_get_buffer( a, &n, NULL ); - memcpy( s+2, tmp, n ); - gcry_free(tmp); + else if (format == GCRYMPI_FMT_PGP) + { + unsigned int n = (nbits + 7)/8; + + /* The PGP format can only handle unsigned integers. */ + if( a->sign ) + return gcry_error (GPG_ERR_INV_ARG); + + if (buffer && n+2 > len) + return gcry_error (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, &n, NULL); + memcpy (s+2, tmp, n); + gcry_free (tmp); } - *nwritten = n+2; - return gcry_error (GPG_ERR_NO_ERROR); + *nwritten = n+2; + return 0; } - else if( format == GCRYMPI_FMT_SSH ) { - unsigned char *tmp; - int extra = 0; - unsigned int n; - - if( a->sign ) - return gcry_error (GPG_ERR_INTERNAL); /* can't handle it yet */ - - tmp = _gcry_mpi_get_buffer( a, &n, NULL ); - if( n && (*tmp & 0x80) ) { - n++; - extra=1; + else if (format == GCRYMPI_FMT_SSH) + { + unsigned char *tmp; + int extra = 0; + unsigned int n; + + if (a->sign) + return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */ + + tmp = _gcry_mpi_get_buffer (a, &n, NULL); + if (n && (*tmp & 0x80)) + { + n++; + extra=1; } - if (buffer && n+4 > len) { - gcry_free(tmp); - return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */ + if (buffer && n+4 > len) + { + gcry_free(tmp); + return gcry_error (GPG_ERR_TOO_SHORT); } - if( buffer ) { - byte *s = buffer; - *s++ = n >> 24; - *s++ = n >> 16; - *s++ = n >> 8; - *s++ = n; - if( extra ) - *s++ = 0; - - memcpy( s, tmp, n-extra ); + + if (buffer) + { + unsigned char *s = buffer; + + *s++ = n >> 24; + *s++ = n >> 16; + *s++ = n >> 8; + *s++ = n; + if (extra) + *s++ = 0; + + memcpy (s, tmp, n-extra); } - gcry_free(tmp); - *nwritten = 4+n; - return gcry_error (GPG_ERR_NO_ERROR); + gcry_free (tmp); + *nwritten = 4+n; + return 0; } - else if( format == GCRYMPI_FMT_HEX ) { - byte *tmp; - int i; - int extra = 0; - unsigned int n=0; - - tmp = _gcry_mpi_get_buffer( a, &n, NULL ); - if( !n || (*tmp & 0x80) ) - extra=2; - - if(buffer && 2*n + extra + !!a->sign + 1 > len) { - gcry_free(tmp); - return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */ + else if (format == GCRYMPI_FMT_HEX) + { + unsigned char *tmp; + int i; + int extra = 0; + unsigned int n = 0; + + tmp = _gcry_mpi_get_buffer (a, &n, NULL); + if (!n || (*tmp & 0x80)) + extra = 2; + + if (buffer && 2*n + extra + !!a->sign + 1 > len) + { + gcry_free(tmp); + return gcry_error (GPG_ERR_TOO_SHORT); } - if( buffer ) { - byte *s = buffer; - if( a->sign ) - *s++ = '-'; - if( extra ) { - *s++ = '0'; - *s++ = '0'; + if (buffer) + { + unsigned char *s = buffer; + + if (a->sign) + *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 ; + + 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; + *s++ = 0; + *nwritten = s - buffer; } - else { - *nwritten = 2*n + extra + !!a->sign + 1; + else + { + *nwritten = 2*n + extra + !!a->sign + 1; } - gcry_free(tmp); - return gcry_error (GPG_ERR_NO_ERROR); + gcry_free (tmp); + return 0; } - else - return gcry_error (GPG_ERR_INV_ARG); + else + return gcry_error (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 + * The caller has to supply the address of a pointer. NWRITTEN may be * NULL. */ gcry_error_t -gcry_mpi_aprint( enum gcry_mpi_format format, +gcry_mpi_aprint (enum gcry_mpi_format format, unsigned char **buffer, size_t *nwritten, - struct gcry_mpi *a ) + struct gcry_mpi *a) { - size_t n; - gcry_error_t rc; - - *buffer = NULL; - rc = gcry_mpi_print( format, NULL, 0, &n, a ); - if( rc ) - return rc; - *buffer = mpi_is_secure(a) ? gcry_xmalloc_secure( n ) : gcry_xmalloc( n ); - rc = gcry_mpi_print( format, *buffer, n, &n, a ); - if( rc ) { - gcry_free(*buffer); - *buffer = NULL; - } - else if( nwritten ) - *nwritten = n; + size_t n; + gcry_error_t rc; + + *buffer = NULL; + rc = gcry_mpi_print (format, NULL, 0, &n, a); + if (rc) return rc; + + *buffer = mpi_is_secure(a) ? gcry_xmalloc_secure( n ) : gcry_xmalloc( n ); + rc = gcry_mpi_print( format, *buffer, n, &n, a ); + if (rc) + { + gcry_free(*buffer); + *buffer = NULL; + } + else if (nwritten) + *nwritten = n; + return rc; } |