Move mbedtls_cf_mem_move_to_left function to the constant-time module

Signed-off-by: Gabor Mezei <gabor.mezei@arm.com>
This commit is contained in:
gabor-mezei-arm 2021-09-27 13:31:06 +02:00 committed by Gabor Mezei
parent 043192d209
commit 7b23c0b46d
No known key found for this signature in database
GPG Key ID: 106F5A41ECC305BD
3 changed files with 45 additions and 41 deletions

View File

@ -354,3 +354,44 @@ void mbedtls_cf_mpi_uint_cond_assign( size_t n,
} }
#endif /* MBEDTLS_BIGNUM_C */ #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 );
}
}

View File

@ -65,3 +65,7 @@ void mbedtls_cf_mpi_uint_cond_assign( size_t n,
unsigned char assign ); unsigned char assign );
#endif /* MBEDTLS_BIGNUM_C */ #endif /* MBEDTLS_BIGNUM_C */
void mbedtls_cf_mem_move_to_left( void *start,
size_t total,
size_t offset );

View File

@ -1479,47 +1479,6 @@ cleanup:
#endif /* MBEDTLS_PKCS1_V21 */ #endif /* MBEDTLS_PKCS1_V21 */
#if defined(MBEDTLS_PKCS1_V15) #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 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
*/ */