mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-22 22:55:39 +01:00
Merge pull request #709 from mpg/protect-base-blinding-dev-restricted
Protect base blinding in RSA and DHM
This commit is contained in:
commit
171826550f
6
ChangeLog.d/protect-base-blinding.txt
Normal file
6
ChangeLog.d/protect-base-blinding.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Security
|
||||||
|
* Fix side channel in RSA private key operations and static (finite-field)
|
||||||
|
Diffie-Hellman. An adversary with precise enough timing and memory access
|
||||||
|
information (typically an untrusted operating system attacking a secure
|
||||||
|
enclave) could bypass an existing counter-measure (base blinding) and
|
||||||
|
potentially fully recover the private key.
|
@ -320,6 +320,32 @@ cleanup:
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pick a random R in the range [2, M) for blinding purposes
|
||||||
|
*/
|
||||||
|
static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||||
|
{
|
||||||
|
int ret, count;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, mbedtls_mpi_size( M ), f_rng, p_rng ) );
|
||||||
|
|
||||||
|
while( mbedtls_mpi_cmp_mpi( R, M ) >= 0 )
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, 1 ) );
|
||||||
|
|
||||||
|
if( count++ > 10 )
|
||||||
|
return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
|
||||||
|
}
|
||||||
|
while( mbedtls_mpi_cmp_int( R, 1 ) <= 0 );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use the blinding method and optimisation suggested in section 10 of:
|
* Use the blinding method and optimisation suggested in section 10 of:
|
||||||
* KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
|
* KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
|
||||||
@ -329,7 +355,10 @@ cleanup:
|
|||||||
static int dhm_update_blinding( mbedtls_dhm_context *ctx,
|
static int dhm_update_blinding( mbedtls_dhm_context *ctx,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||||
{
|
{
|
||||||
int ret, count;
|
int ret;
|
||||||
|
mbedtls_mpi R;
|
||||||
|
|
||||||
|
mbedtls_mpi_init( &R );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't use any blinding the first time a particular X is used,
|
* Don't use any blinding the first time a particular X is used,
|
||||||
@ -364,24 +393,23 @@ static int dhm_update_blinding( mbedtls_dhm_context *ctx,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Vi = random( 2, P-1 ) */
|
/* Vi = random( 2, P-1 ) */
|
||||||
count = 0;
|
MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) );
|
||||||
do
|
|
||||||
{
|
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ) );
|
|
||||||
|
|
||||||
while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 )
|
/* Vf = Vi^-X mod P
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) );
|
* First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
|
||||||
|
* then elevate to the Xth power. */
|
||||||
|
MBEDTLS_MPI_CHK( dhm_random_below( &R, &ctx->P, f_rng, p_rng ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vi, &R ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &R ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
||||||
|
|
||||||
if( count++ > 10 )
|
|
||||||
return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
|
|
||||||
}
|
|
||||||
while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
|
|
||||||
|
|
||||||
/* Vf = Vi^-X mod P */
|
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
|
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
|
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
mbedtls_mpi_free( &R );
|
||||||
|
|
||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -778,6 +778,9 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
|
|||||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||||
{
|
{
|
||||||
int ret, count = 0;
|
int ret, count = 0;
|
||||||
|
mbedtls_mpi R;
|
||||||
|
|
||||||
|
mbedtls_mpi_init( &R );
|
||||||
|
|
||||||
if( ctx->Vf.p != NULL )
|
if( ctx->Vf.p != NULL )
|
||||||
{
|
{
|
||||||
@ -793,18 +796,41 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
|
|||||||
/* Unblinding value: Vf = random number, invertible mod N */
|
/* Unblinding value: Vf = random number, invertible mod N */
|
||||||
do {
|
do {
|
||||||
if( count++ > 10 )
|
if( count++ > 10 )
|
||||||
return( MBEDTLS_ERR_RSA_RNG_FAILED );
|
{
|
||||||
|
ret = MBEDTLS_ERR_RSA_RNG_FAILED;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
|
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
|
|
||||||
} while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
|
|
||||||
|
|
||||||
/* Blinding value: Vi = Vf^(-e) mod N */
|
/* Compute Vf^-1 as R * (R Vf)^-1 to avoid leaks from inv_mod. */
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
|
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, ctx->len - 1, f_rng, p_rng ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vf, &R ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
|
||||||
|
|
||||||
|
/* At this point, Vi is invertible mod N if and only if both Vf and R
|
||||||
|
* are invertible mod N. If one of them isn't, we don't need to know
|
||||||
|
* which one, we just loop and choose new values for both of them.
|
||||||
|
* (Each iteration succeeds with overwhelming probability.) */
|
||||||
|
ret = mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vi, &ctx->N );
|
||||||
|
if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
|
||||||
|
continue;
|
||||||
|
if( ret != 0 )
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
|
||||||
|
} while( 0 );
|
||||||
|
|
||||||
|
/* Blinding value: Vi = Vf^(-e) mod N
|
||||||
|
* (Vi already contains Vf^-1 at this point) */
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
|
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
|
||||||
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
mbedtls_mpi_free( &R );
|
||||||
|
|
||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user