mpi_exp_mod: remove memory ownership confusion

Elements of W didn't all have the same owner: all were owned by this
function, except W[x_index]. It is more robust if we make a proper copy
of X.

Signed-off-by: Janos Follath <janos.follath@arm.com>
diff --git a/library/bignum.c b/library/bignum.c
index 02c0f8a..8a4e67a 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -2043,16 +2043,6 @@
         wsize = MBEDTLS_MPI_WINDOW_SIZE;
 #endif
 
-    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
-     * large enough, and later we'll grow other W[i] to the same length.
-     * They must not be shrunk midway through this function!
-     */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1],  j ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
-
     /*
      * If we call mpi_montmul() without doing a table lookup first, we leak
      * through timing side channels the fact that a squaring is happening. In
@@ -2061,14 +2051,23 @@
      * To prevent this leak, we append the output variable to the end of the
      * table. This allows as to always do a constant time lookup whenever we
      * call mpi_montmul().
+     *
+     * To achieve this, we make a copy of X and we use the table entry in each
+     * calculation from this point on.
      */
     const size_t x_index = w_count - 1;
-    /*
-     * To prevent the leak, we need to use the table entry in each calculation
-     * from this point on. This makes it safe to load X into the table by a
-     * simple assignment.
+    mbedtls_mpi_init( &W[x_index] );
+    mbedtls_mpi_copy( &W[x_index], X );
+
+    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
+     * large enough, and later we'll grow other W[i] to the same length.
+     * They must not be shrunk midway through this function!
      */
-    W[x_index] = *X;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[x_index], j ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1],  j ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
 
     /*
      * Compensate for negative A (and correct at the end)
@@ -2245,14 +2244,17 @@
     /*
      * Load the result in the output variable.
      */
-    *X = W[x_index];
+    mbedtls_mpi_copy( X, &W[x_index] );
 
 cleanup:
 
     for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
         mbedtls_mpi_free( &W[i] );
 
-    mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
+    mbedtls_mpi_free( &W[1] );
+    mbedtls_mpi_free( &W[x_index] );
+    mbedtls_mpi_free( &T );
+    mbedtls_mpi_free( &Apos );
     mbedtls_mpi_free( &WW );
 
     if( prec_RR == NULL || prec_RR->p == NULL )