diff --git a/library/constant_time.c b/library/constant_time.c index b48305a1f..281df6400 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -354,3 +354,44 @@ void mbedtls_cf_mpi_uint_cond_assign( size_t n, } #endif /* MBEDTLS_BIGNUM_C */ + +/** Shift some data towards the left inside a buffer without leaking + * the length of the data through side channels. + * + * `mbedtls_cf_mem_move_to_left(start, total, offset)` is functionally + * equivalent to + * ``` + * memmove(start, start + offset, total - offset); + * memset(start + offset, 0, total - offset); + * ``` + * but it strives to use a memory access pattern (and thus total timing) + * that does not depend on \p offset. This timing independence comes at + * the expense of performance. + * + * \param start Pointer to the start of the buffer. + * \param total Total size of the buffer. + * \param offset Offset from which to copy \p total - \p offset bytes. + */ +void mbedtls_cf_mem_move_to_left( void *start, + size_t total, + size_t offset ) +{ + volatile unsigned char *buf = start; + size_t i, n; + if( total == 0 ) + return; + for( i = 0; i < total; i++ ) + { + unsigned no_op = mbedtls_cf_size_gt( total - offset, i ); + /* The first `total - offset` passes are a no-op. The last + * `offset` passes shift the data one byte to the left and + * zero out the last byte. */ + for( n = 0; n < total - 1; n++ ) + { + unsigned char current = buf[n]; + unsigned char next = buf[n+1]; + buf[n] = mbedtls_cf_uint_if( no_op, current, next ); + } + buf[total-1] = mbedtls_cf_uint_if( no_op, buf[total-1], 0 ); + } +} diff --git a/library/constant_time.h b/library/constant_time.h index 588181ec9..5a932cc6f 100644 --- a/library/constant_time.h +++ b/library/constant_time.h @@ -65,3 +65,7 @@ void mbedtls_cf_mpi_uint_cond_assign( size_t n, unsigned char assign ); #endif /* MBEDTLS_BIGNUM_C */ + +void mbedtls_cf_mem_move_to_left( void *start, + size_t total, + size_t offset ); diff --git a/library/rsa.c b/library/rsa.c index 2cee36f27..b8be89ca7 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -1479,47 +1479,6 @@ cleanup: #endif /* MBEDTLS_PKCS1_V21 */ #if defined(MBEDTLS_PKCS1_V15) -/** Shift some data towards the left inside a buffer without leaking - * the length of the data through side channels. - * - * `mbedtls_cf_mem_move_to_left(start, total, offset)` is functionally - * equivalent to - * ``` - * memmove(start, start + offset, total - offset); - * memset(start + offset, 0, total - offset); - * ``` - * but it strives to use a memory access pattern (and thus total timing) - * that does not depend on \p offset. This timing independence comes at - * the expense of performance. - * - * \param start Pointer to the start of the buffer. - * \param total Total size of the buffer. - * \param offset Offset from which to copy \p total - \p offset bytes. - */ -static void mbedtls_cf_mem_move_to_left( void *start, - size_t total, - size_t offset ) -{ - volatile unsigned char *buf = start; - size_t i, n; - if( total == 0 ) - return; - for( i = 0; i < total; i++ ) - { - unsigned no_op = mbedtls_cf_size_gt( total - offset, i ); - /* The first `total - offset` passes are a no-op. The last - * `offset` passes shift the data one byte to the left and - * zero out the last byte. */ - for( n = 0; n < total - 1; n++ ) - { - unsigned char current = buf[n]; - unsigned char next = buf[n+1]; - buf[n] = mbedtls_cf_uint_if( no_op, current, next ); - } - buf[total-1] = mbedtls_cf_uint_if( no_op, buf[total-1], 0 ); - } -} - /* * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function */