diff --git a/library/bignum.c b/library/bignum.c index a97bbe9f4..7caace776 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -269,36 +269,6 @@ void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ) memcpy( Y, &T, sizeof( mbedtls_mpi ) ); } -/** - * Select between two sign values in constant-time. - * - * This is functionally equivalent to second ? a : b but uses only bit - * operations in order to avoid branches. - * - * \param[in] a The first sign; must be either +1 or -1. - * \param[in] b The second sign; must be either +1 or -1. - * \param[in] second Must be either 1 (return b) or 0 (return a). - * - * \return The selected sign value. - */ -static int mbedtls_cf_cond_select_sign( int a, int b, unsigned char second ) -{ - /* In order to avoid questions about what we can reasonnably assume about - * the representations of signed integers, move everything to unsigned - * by taking advantage of the fact that a and b are either +1 or -1. */ - unsigned ua = a + 1; - unsigned ub = b + 1; - - /* second was 0 or 1, mask is 0 or 2 as are ua and ub */ - const unsigned mask = second << 1; - - /* select ua or ub */ - unsigned ur = ( ua & ~mask ) | ( ub & mask ); - - /* ur is now 0 or 2, convert back to -1 or +1 */ - return( (int) ur - 1 ); -} - /* * Conditionally assign dest = src, without leaking information * about whether the assignment was made or not. diff --git a/library/constant_time.c b/library/constant_time.c index 6d531345c..6f59884ef 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -289,3 +289,33 @@ unsigned mbedtls_cf_uint_if( unsigned cond, unsigned if1, unsigned if0 ) unsigned mask = mbedtls_cf_uint_mask( cond ); return( ( mask & if1 ) | (~mask & if0 ) ); } + +/** + * Select between two sign values in constant-time. + * + * This is functionally equivalent to second ? a : b but uses only bit + * operations in order to avoid branches. + * + * \param[in] a The first sign; must be either +1 or -1. + * \param[in] b The second sign; must be either +1 or -1. + * \param[in] second Must be either 1 (return b) or 0 (return a). + * + * \return The selected sign value. + */ +int mbedtls_cf_cond_select_sign( int a, int b, unsigned char second ) +{ + /* In order to avoid questions about what we can reasonnably assume about + * the representations of signed integers, move everything to unsigned + * by taking advantage of the fact that a and b are either +1 or -1. */ + unsigned ua = a + 1; + unsigned ub = b + 1; + + /* second was 0 or 1, mask is 0 or 2 as are ua and ub */ + const unsigned mask = second << 1; + + /* select ua or ub */ + unsigned ur = ( ua & ~mask ) | ( ub & mask ); + + /* ur is now 0 or 2, convert back to -1 or +1 */ + return( (int) ur - 1 ); +} diff --git a/library/constant_time.h b/library/constant_time.h index 973e856d6..f97c57e7c 100644 --- a/library/constant_time.h +++ b/library/constant_time.h @@ -55,3 +55,4 @@ unsigned mbedtls_cf_mpi_uint_lt( const mbedtls_mpi_uint x, unsigned mbedtls_cf_uint_if( unsigned cond, unsigned if1, unsigned if0 ); +int mbedtls_cf_cond_select_sign( int a, int b, unsigned char second );