Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove a secret-dependent branch in Montgomery multiplication #3398

Merged
Merged
24 changes: 15 additions & 9 deletions library/bignum.c
Original file line number Diff line number Diff line change
Expand Up @@ -1374,20 +1374,20 @@ static mbedtls_mpi_uint mpi_sub_hlp( size_t n,
}

/*
* Unsigned subtraction: X = |A| - |B| (HAC 14.9)
* Unsigned subtraction: X = |A| - |B| (HAC 14.9, 14.10)
*/
int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
mbedtls_mpi TB;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
mbedtls_mpi_uint c, z;
mbedtls_mpi_uint carry;
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL );
MPI_VALIDATE_RET( B != NULL );

if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initial check that A >= B is no longer needed, since the function now checks that the carry propagation terminates, which is equivalent.

Oops. The carry propagation check is equivalent, but that's assuming it is reached. If B->n > A->n, or more precisely if B without leading null limbs is larger than A (with its leading null limbs), then mpi_sub_hlp overflows X->p.

return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
/* if( mbedtls_mpi_cmp_abs( A, B ) < 0 ) */
/* return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was it your intention to leave this code commented, or did you mean to remove it?


mbedtls_mpi_init( &TB );

Expand All @@ -1411,11 +1411,17 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
if( B->p[n - 1] != 0 )
break;

c = mpi_sub_hlp( n, X->p, B->p );
while( c != 0 )
{
z = ( X->p[n] < c ); X->p[n] -= c;
c = z; n++;
carry = mpi_sub_hlp( n, X->p, B->p );
if( carry != 0 )
{
/* Propagate the carry to the first nonzero limb of X. */
for( ; n < X->n && X->p[n] == 0; n++ )
--X->p[n];
/* If we ran out of space for the carry, it means that the result
* is negative. */
if( n == X->n )
return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
--X->p[n];
}

cleanup:
Expand Down