mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-26 03:45:38 +01:00
Simplify usage of DHM blinding
This commit is contained in:
parent
c83e418149
commit
15d5de1969
@ -230,13 +230,11 @@ int dhm_make_public( dhm_context *ctx, int x_size,
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
|
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
|
||||||
*
|
*
|
||||||
* \note If f_rng is not NULL, it is used to blind the input as
|
* \note If non-NULL, f_rng is used to blind the input as
|
||||||
* countermeasure against timing attacks. This is only useful
|
* countermeasure against timing attacks. Blinding is
|
||||||
* when this function is called repeatedly with the same
|
* automatically used if and only if our secret value X is
|
||||||
* secret value (X field), eg when using DH key exchange as
|
* re-used and costs nothing otherwise, so it is recommended
|
||||||
* opposed to DHE. It is recommended to use a non-NULL f_rng
|
* to always pass a non-NULL f_rng argument.
|
||||||
* only when needed, since otherwise this countermeasure has
|
|
||||||
* high overhead.
|
|
||||||
*/
|
*/
|
||||||
int dhm_calc_secret( dhm_context *ctx,
|
int dhm_calc_secret( dhm_context *ctx,
|
||||||
unsigned char *output, size_t *olen,
|
unsigned char *output, size_t *olen,
|
||||||
|
@ -273,51 +273,55 @@ static int dhm_update_blinding( dhm_context *ctx,
|
|||||||
int ret, count;
|
int ret, count;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If Vi is initialized, update it by squaring it
|
* Don't use any blinding the first time a particular X is used,
|
||||||
|
* but remember it to use blinding next time.
|
||||||
*/
|
*/
|
||||||
if( ctx->Vi.p != NULL )
|
if( mpi_cmp_mpi( &ctx->X, &ctx->_X ) != 0 )
|
||||||
{
|
{
|
||||||
MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
|
MPI_CHK( mpi_copy( &ctx->_X, &ctx->X ) );
|
||||||
MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
|
MPI_CHK( mpi_lset( &ctx->Vi, 1 ) );
|
||||||
}
|
MPI_CHK( mpi_lset( &ctx->Vf, 1 ) );
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Vi = random( 2, P-1 ) */
|
|
||||||
count = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
mpi_fill_random( &ctx->Vi, mpi_size( &ctx->P ), f_rng, p_rng );
|
|
||||||
|
|
||||||
while( mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 )
|
|
||||||
mpi_shift_r( &ctx->Vi, 1 );
|
|
||||||
|
|
||||||
if( count++ > 10 )
|
|
||||||
return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
|
|
||||||
}
|
|
||||||
while( mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If X did not change, update Vf by squaring it too
|
|
||||||
*/
|
|
||||||
if( mpi_cmp_mpi( &ctx->X, &ctx->_X ) == 0 )
|
|
||||||
{
|
|
||||||
MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
|
|
||||||
MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Otherwise, compute Vf from scratch
|
* Ok, we need blinding. Can we re-use existing values?
|
||||||
|
* If yes, just update them by squaring them.
|
||||||
*/
|
*/
|
||||||
|
if( mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
|
||||||
|
{
|
||||||
|
MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
|
||||||
|
|
||||||
|
MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to generate blinding values from scratch
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Vi = random( 2, P-1 ) */
|
||||||
|
count = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
mpi_fill_random( &ctx->Vi, mpi_size( &ctx->P ), f_rng, p_rng );
|
||||||
|
|
||||||
|
while( mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 )
|
||||||
|
mpi_shift_r( &ctx->Vi, 1 );
|
||||||
|
|
||||||
|
if( count++ > 10 )
|
||||||
|
return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
|
||||||
|
}
|
||||||
|
while( mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
|
||||||
|
|
||||||
/* Vf = Vi^-X mod P */
|
/* Vf = Vi^-X mod P */
|
||||||
MPI_CHK( mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
|
MPI_CHK( mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
|
||||||
MPI_CHK( mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
|
MPI_CHK( mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
|
||||||
|
|
||||||
/* Remember secret associated with Vi and Vf */
|
|
||||||
MPI_CHK( mpi_copy( &ctx->_X, &ctx->X ) );;
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
@ -1702,11 +1702,10 @@ static int ssl_write_client_key_exchange( ssl_context *ssl )
|
|||||||
|
|
||||||
ssl->handshake->pmslen = ssl->handshake->dhm_ctx.len;
|
ssl->handshake->pmslen = ssl->handshake->dhm_ctx.len;
|
||||||
|
|
||||||
/* No blinding needed for DHE, but will be needed for fixed DH! */
|
|
||||||
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
||||||
ssl->handshake->premaster,
|
ssl->handshake->premaster,
|
||||||
&ssl->handshake->pmslen,
|
&ssl->handshake->pmslen,
|
||||||
NULL, NULL ) ) != 0 )
|
ssl->f_rng, ssl->p_rng ) ) != 0 )
|
||||||
{
|
{
|
||||||
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
||||||
return( ret );
|
return( ret );
|
||||||
@ -1834,9 +1833,8 @@ static int ssl_write_client_key_exchange( ssl_context *ssl )
|
|||||||
|
|
||||||
*(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len >> 8 );
|
*(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len >> 8 );
|
||||||
*(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len );
|
*(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len );
|
||||||
/* No blinding needed since this is ephemeral DHM */
|
|
||||||
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
||||||
p, &n, NULL, NULL ) ) != 0 )
|
p, &n, ssl->f_rng, ssl->p_rng ) ) != 0 )
|
||||||
{
|
{
|
||||||
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
||||||
return( ret );
|
return( ret );
|
||||||
|
@ -2373,7 +2373,7 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl )
|
|||||||
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
||||||
ssl->handshake->premaster,
|
ssl->handshake->premaster,
|
||||||
&ssl->handshake->pmslen,
|
&ssl->handshake->pmslen,
|
||||||
NULL, NULL ) ) != 0 )
|
ssl->f_rng, ssl->p_rng ) ) != 0 )
|
||||||
{
|
{
|
||||||
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
||||||
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
|
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
|
||||||
@ -2460,7 +2460,7 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl )
|
|||||||
|
|
||||||
/* No blinding needed since this is ephemeral DHM */
|
/* No blinding needed since this is ephemeral DHM */
|
||||||
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
||||||
p, &n, NULL, NULL ) ) != 0 )
|
p, &n, ssl->f_rng, ssl->p_rng ) ) != 0 )
|
||||||
{
|
{
|
||||||
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
||||||
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
|
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
|
||||||
|
@ -239,7 +239,8 @@ int main( int argc, char *argv[] )
|
|||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
|
|
||||||
n = dhm.len;
|
n = dhm.len;
|
||||||
if( ( ret = dhm_calc_secret( &dhm, buf, &n, NULL, NULL ) ) != 0 )
|
if( ( ret = dhm_calc_secret( &dhm, buf, &n,
|
||||||
|
ctr_drbg_random, &ctr_drbg ) ) != 0 )
|
||||||
{
|
{
|
||||||
printf( " failed\n ! dhm_calc_secret returned %d\n\n", ret );
|
printf( " failed\n ! dhm_calc_secret returned %d\n\n", ret );
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -242,7 +242,8 @@ int main( int argc, char *argv[] )
|
|||||||
printf( "\n . Shared secret: " );
|
printf( "\n . Shared secret: " );
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
|
|
||||||
if( ( ret = dhm_calc_secret( &dhm, buf, &n, NULL, NULL ) ) != 0 )
|
if( ( ret = dhm_calc_secret( &dhm, buf, &n,
|
||||||
|
ctr_drbg_random, &ctr_drbg ) ) != 0 )
|
||||||
{
|
{
|
||||||
printf( " failed\n ! dhm_calc_secret returned %d\n\n", ret );
|
printf( " failed\n ! dhm_calc_secret returned %d\n\n", ret );
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -558,7 +558,7 @@ int main( int argc, char *argv[] )
|
|||||||
{
|
{
|
||||||
olen = sizeof( buf );
|
olen = sizeof( buf );
|
||||||
ret |= dhm_make_public( &dhm, dhm.len, buf, dhm.len, myrand, NULL );
|
ret |= dhm_make_public( &dhm, dhm.len, buf, dhm.len, myrand, NULL );
|
||||||
ret |= dhm_calc_secret( &dhm, buf, &olen, NULL, NULL );
|
ret |= dhm_calc_secret( &dhm, buf, &olen, myrand, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ret != 0 )
|
if( ret != 0 )
|
||||||
@ -617,7 +617,7 @@ int main( int argc, char *argv[] )
|
|||||||
for( i = 1; ! alarmed && ! ret ; i++ )
|
for( i = 1; ! alarmed && ! ret ; i++ )
|
||||||
{
|
{
|
||||||
olen = sizeof( buf );
|
olen = sizeof( buf );
|
||||||
ret |= dhm_calc_secret( &dhm, buf, &olen, NULL, NULL );
|
ret |= dhm_calc_secret( &dhm, buf, &olen, myrand, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ret != 0 )
|
if( ret != 0 )
|
||||||
@ -643,7 +643,7 @@ int main( int argc, char *argv[] )
|
|||||||
{
|
{
|
||||||
olen = sizeof( buf );
|
olen = sizeof( buf );
|
||||||
ret |= dhm_make_public( &dhm, dhm.len, buf, dhm.len, myrand, NULL );
|
ret |= dhm_make_public( &dhm, dhm.len, buf, dhm.len, myrand, NULL );
|
||||||
ret |= dhm_calc_secret( &dhm, buf, &olen, NULL, NULL );
|
ret |= dhm_calc_secret( &dhm, buf, &olen, myrand, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ret != 0 )
|
if( ret != 0 )
|
||||||
|
@ -22,7 +22,7 @@ void dhm_do_dhm( int radix_P, char *input_P,
|
|||||||
size_t pub_cli_len = 0;
|
size_t pub_cli_len = 0;
|
||||||
size_t sec_srv_len = 1000;
|
size_t sec_srv_len = 1000;
|
||||||
size_t sec_cli_len = 1000;
|
size_t sec_cli_len = 1000;
|
||||||
int x_size;
|
int x_size, i;
|
||||||
rnd_pseudo_info rnd_info;
|
rnd_pseudo_info rnd_info;
|
||||||
|
|
||||||
memset( &ctx_srv, 0x00, sizeof( dhm_context ) );
|
memset( &ctx_srv, 0x00, sizeof( dhm_context ) );
|
||||||
@ -59,13 +59,16 @@ void dhm_do_dhm( int radix_P, char *input_P,
|
|||||||
TEST_ASSERT( sec_srv_len != 0 );
|
TEST_ASSERT( sec_srv_len != 0 );
|
||||||
TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
|
TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
|
||||||
|
|
||||||
/* Re-do calc_secret on server to test update of blinding values */
|
/* Re-do calc_secret on server a few times to test update of blinding values */
|
||||||
sec_srv_len = 1000;
|
for( i = 0; i < 3; i++ )
|
||||||
TEST_ASSERT( dhm_calc_secret( &ctx_srv, sec_srv, &sec_srv_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
|
{
|
||||||
|
sec_srv_len = 1000;
|
||||||
|
TEST_ASSERT( dhm_calc_secret( &ctx_srv, sec_srv, &sec_srv_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||||
|
|
||||||
TEST_ASSERT( sec_srv_len == sec_cli_len );
|
TEST_ASSERT( sec_srv_len == sec_cli_len );
|
||||||
TEST_ASSERT( sec_srv_len != 0 );
|
TEST_ASSERT( sec_srv_len != 0 );
|
||||||
TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
|
TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Second key exchange to test change of blinding values on server
|
* Second key exchange to test change of blinding values on server
|
||||||
|
Loading…
Reference in New Issue
Block a user