diff --git a/ChangeLog b/ChangeLog index 60e0f774c..e562139f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,8 @@ Bugfix #52) * Fixed possible segfault in mpi_shift_r() (found by Manuel Pégourié-Gonnard) + * Allow R and A to point to same mpi in mpi_div_mpi (found by Manuel + Pégourié-Gonnard) Security * Fixed potential memory zeroization on miscrafted RSA key (found by Eloi diff --git a/library/bignum.c b/library/bignum.c index acaba6a7e..079b58ee9 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -1196,9 +1196,9 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ) if( R != NULL ) { mpi_shift_r( &X, k ); + X.s = A->s; mpi_copy( R, &X ); - R->s = A->s; if( mpi_cmp_int( R, 0 ) == 0 ) R->s = 1; } @@ -1399,19 +1399,6 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) if( mpi_cmp_int( E, 0 ) < 0 ) return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - /* - * Compensate for negative A (and correct at the end) - */ - neg = ( A->s == -1 ); - - mpi_init( &Apos ); - if( neg ) - { - MPI_CHK( mpi_copy( &Apos, A ) ); - Apos.s = 1; - A = &Apos; - } - /* * Init temps and window size */ @@ -1432,6 +1419,19 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) MPI_CHK( mpi_grow( &W[1], j ) ); MPI_CHK( mpi_grow( &T, j * 2 ) ); + /* + * Compensate for negative A (and correct at the end) + */ + neg = ( A->s == -1 ); + + mpi_init( &Apos ); + if( neg ) + { + MPI_CHK( mpi_copy( &Apos, A ) ); + Apos.s = 1; + A = &Apos; + } + /* * If 1st call, pre-compute R^2 mod N */ diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function index 596b7df6d..70d9b4f18 100644 --- a/tests/suites/test_suite_mpi.function +++ b/tests/suites/test_suite_mpi.function @@ -514,21 +514,21 @@ END_CASE BEGIN_CASE mpi_mod_mpi:radix_X:input_X:radix_Y:input_Y:radix_A:input_A:div_result { - mpi X, Y, Z, A; + mpi X, Y, A; int res; - mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z ); mpi_init( &A ); + mpi_init( &X ); mpi_init( &Y ); mpi_init( &A ); TEST_ASSERT( mpi_read_string( &X, {radix_X}, {input_X} ) == 0 ); TEST_ASSERT( mpi_read_string( &Y, {radix_Y}, {input_Y} ) == 0 ); TEST_ASSERT( mpi_read_string( &A, {radix_A}, {input_A} ) == 0 ); - res = mpi_mod_mpi( &Z, &X, &Y ); + res = mpi_mod_mpi( &X, &X, &Y ); TEST_ASSERT( res == {div_result} ); if( res == 0 ) { - TEST_ASSERT( mpi_cmp_mpi( &Z, &A ) == 0 ); + TEST_ASSERT( mpi_cmp_mpi( &X, &A ) == 0 ); } - mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z ); mpi_free( &A ); + mpi_free( &X ); mpi_free( &Y ); mpi_free( &A ); } END_CASE