mbedtls_mpi_write_binary: don't leak the exact size of the number
In mbedtls_mpi_write_binary, avoid leaking the size of the number through timing or branches, if possible. More precisely, if the number fits in the output buffer based on its allocated size, the new code's trace doesn't depend on the value of the number.
This commit is contained in:
parent
4899247bf2
commit
11cdb0559e
1 changed files with 35 additions and 10 deletions
|
@ -321,6 +321,10 @@ int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
|
|||
return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
|
||||
}
|
||||
|
||||
/* Get a specific byte, without range checks. */
|
||||
#define GET_BYTE( X, i ) \
|
||||
( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff )
|
||||
|
||||
/*
|
||||
* Set a bit to a specific value of 0 or 1
|
||||
*/
|
||||
|
@ -704,19 +708,40 @@ cleanup:
|
|||
/*
|
||||
* Export X into unsigned binary data, big endian
|
||||
*/
|
||||
int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen )
|
||||
int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
|
||||
unsigned char *buf, size_t buflen )
|
||||
{
|
||||
size_t i, j, n;
|
||||
size_t stored_bytes = X->n * ciL;
|
||||
size_t bytes_to_copy;
|
||||
unsigned char *p;
|
||||
size_t i;
|
||||
|
||||
n = mbedtls_mpi_size( X );
|
||||
if( stored_bytes < buflen )
|
||||
{
|
||||
/* There is enough space in the output buffer. Write initial
|
||||
* null bytes and record the position at which to start
|
||||
* writing the significant bytes. In this case, the execution
|
||||
* trace of this function does not depend on the value of the
|
||||
* number. */
|
||||
bytes_to_copy = stored_bytes;
|
||||
p = buf + buflen - stored_bytes;
|
||||
memset( buf, 0, buflen - stored_bytes );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The output buffer is smaller than the allocated size of X.
|
||||
* However X may fit if its leading bytes are zero. */
|
||||
bytes_to_copy = buflen;
|
||||
p = buf;
|
||||
for( i = bytes_to_copy; i < stored_bytes; i++ )
|
||||
{
|
||||
if( GET_BYTE( X, i ) != 0 )
|
||||
return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
|
||||
}
|
||||
}
|
||||
|
||||
if( buflen < n )
|
||||
return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
|
||||
|
||||
memset( buf, 0, buflen );
|
||||
|
||||
for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
|
||||
buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
|
||||
for( i = 0; i < bytes_to_copy; i++ )
|
||||
p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue