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 committed by bot
parent b0a714476a
commit 2efb3288a0
2 changed files with 4 additions and 8 deletions

View File

@ -564,6 +564,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.)
@ -608,8 +611,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 */
@ -716,9 +717,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) );

View File

@ -449,6 +449,7 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
return mpi_mult_mpi_failover_mod_mult(Z, X, Y, z_words); return mpi_mult_mpi_failover_mod_mult(Z, X, Y, z_words);
} else { } else {
/* Still too long for the hardware unit... */ /* Still too long for the hardware unit... */
mbedtls_mpi_grow(Z, z_words);
if(y_words > x_words) { if(y_words > x_words) {
return mpi_mult_mpi_overlong(Z, X, Y, y_words, z_words); return mpi_mult_mpi_overlong(Z, X, Y, y_words, z_words);
} else { } else {
@ -573,9 +574,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) );