diff --git a/ChangeLog b/ChangeLog index ae2fe7bd4..5c2fbbbd4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,8 @@ Bugfix build error. Fixed by Haijun Gu #2319. * Fix signed-to-unsigned integer conversion warning in X.509 module. Fixes #2212. + * Reduce stack usage of `mpi_write_hlp()` by eliminating recursion. + Fixes #2190. Changes * Include configuration file in all header files that use configuration, diff --git a/library/bignum.c b/library/bignum.c index d3d02b1a0..87015af0c 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -527,26 +527,38 @@ cleanup: } /* - * Helper to write the digits high-order first + * Helper to write the digits high-order first. */ -static int mpi_write_hlp( mbedtls_mpi *X, int radix, char **p ) +static int mpi_write_hlp( mbedtls_mpi *X, int radix, + char **p, const size_t buflen ) { int ret; mbedtls_mpi_uint r; + size_t length = 0; + char *p_end = *p + buflen; - if( radix < 2 || radix > 16 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + do + { + if( length >= buflen ) + { + return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); + } - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) ); + /* + * Write the residue in the current position, as an ASCII character. + */ + if( r < 0xA ) + *(--p_end) = (char)( '0' + r ); + else + *(--p_end) = (char)( 'A' + ( r - 0xA ) ); - if( mbedtls_mpi_cmp_int( X, 0 ) != 0 ) - MBEDTLS_MPI_CHK( mpi_write_hlp( X, radix, p ) ); + length++; + } while( mbedtls_mpi_cmp_int( X, 0 ) != 0 ); - if( r < 10 ) - *(*p)++ = (char)( r + 0x30 ); - else - *(*p)++ = (char)( r + 0x37 ); + memmove( *p, p_end, length ); + *p += length; cleanup: @@ -619,7 +631,7 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, if( T.s == -1 ) T.s = 1; - MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p ) ); + MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p, buflen ) ); } *p++ = '\0';