mbedtls: fix hw accelerated big-num mul if operand and result overlap

this issue is mainly exposed when using larger (4096) client key in TLS mutual auth,
since it uses multiplications > 2048 when mbedtls_mpi_mul_mpi is used in recursion,
which works only if both operands point to different location than result since
mpi_mult_mpi_overlong() called mbedtls_mpi_grow() to reallocate buffers used in previous
pointer arithmetics and thus corrupting it. Fixed by growing the mpi buffer before
calling mpi_mult_mpi_overlong()
This commit is contained in:
David Cermak 2020-01-04 17:18:46 +01:00
parent 12d639e5b2
commit fe5b7b549c

View file

@ -509,6 +509,9 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
return ret; return ret;
} }
/* Grow Z to result size early, avoid interim allocations */
MBEDTLS_MPI_CHK( mbedtls_mpi_grow(Z, z_words) );
/* If either factor is over 2048 bits, we can't use the standard hardware multiplier /* If either factor is over 2048 bits, we can't use the standard hardware multiplier
(it assumes result is double longest factor, and result is max 4096 bits.) (it assumes result is double longest factor, and result is max 4096 bits.)
@ -553,8 +556,6 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
start_op(RSA_MULT_START_REG); start_op(RSA_MULT_START_REG);
MBEDTLS_MPI_CHK( mbedtls_mpi_grow(Z, z_words) );
wait_op_complete(RSA_MULT_START_REG); wait_op_complete(RSA_MULT_START_REG);
/* Read back the result */ /* Read back the result */
@ -661,9 +662,6 @@ static int mpi_mult_mpi_overlong(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbe
}; };
mbedtls_mpi_init(&Ztemp); mbedtls_mpi_init(&Ztemp);
/* Grow Z to result size early, avoid interim allocations */
mbedtls_mpi_grow(Z, z_words);
/* Get result Ztemp = Yp * X (need temporary variable Ztemp) */ /* Get result Ztemp = Yp * X (need temporary variable Ztemp) */
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi(&Ztemp, X, &Yp) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi(&Ztemp, X, &Yp) );