diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index 9d15955f340a..8b83dc89743a 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -837,7 +837,6 @@ int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, * \brief Perform a sliding-window exponentiation: X = A^E mod N * * \param X The destination MPI. This must point to an initialized MPI. - * This must not alias E or N. * \param A The base of the exponentiation. * This must point to an initialized MPI. * \param E The exponent MPI. This must point to an initialized MPI. diff --git a/library/bignum.c b/library/bignum.c index 521787d74908..62c1fa58684c 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -1593,6 +1593,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, size_t bufsize, nbits; mbedtls_mpi_uint ei, mm, state; mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], WW, Apos; + mbedtls_mpi *R = X; int neg; MPI_VALIDATE_RET( X != NULL ); @@ -1629,6 +1630,9 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, wsize = MBEDTLS_MPI_WINDOW_SIZE; #endif + if( X == E || X == N ) + X = &Apos; /* dual-purpose stack var Apos */ + j = N->n + 1; /* All W[i] and X must have at least N->n limbs for the mpi_montmul() * and mpi_montred() calls later. Here we ensure that W[1] and X are @@ -1803,6 +1807,9 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) ); } + if( R != X ) + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, X ) ); + cleanup: for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ ) diff --git a/tests/suites/test_suite_bignum.function b/tests/suites/test_suite_bignum.function index 4cec0a7c7185..d791d8b233f3 100644 --- a/tests/suites/test_suite_bignum.function +++ b/tests/suites/test_suite_bignum.function @@ -1061,6 +1061,39 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void mpi_exp_mod_aliasing( int result ) +{ + mbedtls_mpi X, A, E, N; + mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N ); + (void)result; + + TEST_ASSERT( mbedtls_mpi_lset( &X, 2 ) == 0 ); + TEST_ASSERT( mbedtls_mpi_lset( &E, 3 ) == 0 ); + TEST_ASSERT( mbedtls_mpi_lset( &N, 11 ) == 0 ); + TEST_ASSERT( mbedtls_mpi_exp_mod( &X, &X, &E, &N, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 8 ) == 0 ); + + TEST_ASSERT( mbedtls_mpi_lset( &X, 3 ) == 0 ); + TEST_ASSERT( mbedtls_mpi_lset( &A, 2 ) == 0 ); + TEST_ASSERT( mbedtls_mpi_lset( &N, 11 ) == 0 ); + TEST_ASSERT( mbedtls_mpi_exp_mod( &X, &A, &X, &N, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 8 ) == 0 ); + + TEST_ASSERT( mbedtls_mpi_lset( &X, 3 ) == 0 ); + TEST_ASSERT( mbedtls_mpi_lset( &A, 7 ) == 0 ); + TEST_ASSERT( mbedtls_mpi_exp_mod( &X, &A, &X, &X, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 1 ) == 0 ); + + TEST_ASSERT( mbedtls_mpi_lset( &X, 3 ) == 0 ); + TEST_ASSERT( mbedtls_mpi_exp_mod( &X, &X, &X, &X, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 ); + +exit: + mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); +} +/* END_CASE */ + /* BEGIN_CASE */ void mpi_inv_mod( char * input_X, char * input_Y, char * input_A, int div_result ) diff --git a/tests/suites/test_suite_bignum.misc.data b/tests/suites/test_suite_bignum.misc.data index 29ba4ab46d24..b20cf3bbd1ad 100644 --- a/tests/suites/test_suite_bignum.misc.data +++ b/tests/suites/test_suite_bignum.misc.data @@ -1332,6 +1332,9 @@ Test mbedtls_mpi_exp_mod (Negative base) [#2] depends_on:MPI_MAX_BITS_LARGER_THAN_792 mpi_exp_mod:"-9f13012cd92aa72fb86ac8879d2fde4f7fd661aaae43a00971f081cc60ca277059d5c37e89652e2af2585d281d66ef6a9d38a117e9608e9e7574cd142dc55278838a2161dd56db9470d4c1da2d5df15a908ee2eb886aaa890f23be16de59386663a12f1afbb325431a3e835e3fd89b98b96a6f77382f458ef9a37e1f84a03045c8676ab55291a94c2228ea15448ee96b626b998":"40a54d1b9e86789f06d9607fb158672d64867665c73ee9abb545fc7a785634b354c7bae5b962ce8040cf45f2c1f3d3659b2ee5ede17534c8fc2ec85c815e8df1fe7048d12c90ee31b88a68a081f17f0d8ce5f4030521e9400083bcea73a429031d4ca7949c2000d597088e0c39a6014d8bf962b73bb2e8083bd0390a4e00b9b3":"eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3":"21acc7199e1b90f9b4844ffe12c19f00ec548c5d32b21c647d48b6015d8eb9ec9db05b4f3d44db4227a2b5659c1a7cceb9d5fa8fa60376047953ce7397d90aaeb7465e14e820734f84aa52ad0fc66701bcbb991d57715806a11531268e1e83dd48288c72b424a6287e9ce4e5cc4db0dd67614aecc23b0124a5776d36e5c89483":0 +Test mbedtls_mpi_exp_mod output argument aliasing inputs +mpi_exp_mod_aliasing:0 + Base test GCD #1 mpi_gcd:"2b5":"261":"15"