From fee261a50551fc45938103240ba53a88895f0405 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 6 Apr 2022 06:20:22 +0100 Subject: [PATCH] Adjust mbedtls_mpi_mul_mpi() to new signature of mpi_mul_hlp() The previous commit has changed the signature of mpi_mul_hlp(), making the length of the output explicit. This commit adjusts the call-site in mbedtls_mpi_mul_mpi() to this new signature. A notable change to the multiplication strategy had to be made: mbedtls_mpi_mul_mpi() performs a simple row-wise schoolbook multiplication, which however was so far computed iterating rows from top to bottom. This leads to the undesirable consequence that as lower rows are calculated and added to the temporary result, carry chains can grow. It is simpler and faster to iterate from bottom to top instead, as it is guaranteed that there will be no carry when adding the next row to the previous temporary result: The length of the output in each iteration can be fixed to len(B)+1. Signed-off-by: Hanno Becker --- library/bignum.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/library/bignum.c b/library/bignum.c index b7b90ec3e7..da8e8ca3c7 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -1465,7 +1465,7 @@ mbedtls_mpi_uint mpi_mul_hlp( mbedtls_mpi_uint *d, size_t d_len , int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i, j; + size_t i, j, k; mbedtls_mpi TA, TB; int result_is_zero = 0; MPI_VALIDATE_RET( X != NULL ); @@ -1492,8 +1492,14 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - for( ; j > 0; j-- ) - mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] ); + for( k = 0; k < j; k++ ) + { + /* We know that there cannot be any carry-out since we're + * iterating from bottom to top. */ + (void) mpi_mul_hlp( X->p + k, i + 1, + A->p, i, + B->p[k] ); + } /* If the result is 0, we don't shortcut the operation, which reduces * but does not eliminate side channels leaking the zero-ness. We do