mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-12-23 13:35:28 +00:00
Avoid small private exponents during RSA key generation
Attacks against RSA exist for small D. [Wiener] established this for D < N^0.25. [Boneh] suggests the bound should be N^0.5. Multiple possible values of D might exist for the same set of E, P, Q. The attack works when there exists any possible D that is small. To make sure that the generated key is not susceptible to attack, we need to make sure we have found the smallest possible D, and then check that D is big enough. The Carmichael function λ of p*q is lcm(p-1, q-1), so we can apply Carmichael's theorem to show that D = d mod λ(n) is the smallest. [Wiener] Michael J. Wiener, "Cryptanalysis of Short RSA Secret Exponents" [Boneh] Dan Boneh and Glenn Durfee, "Cryptanalysis of RSA with Private Key d Less than N^0.292"
This commit is contained in:
parent
80aa3b8d65
commit
97f95c9ef3
|
@ -502,7 +502,7 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
|
|||
unsigned int nbits, int exponent )
|
||||
{
|
||||
int ret;
|
||||
mbedtls_mpi H, G;
|
||||
mbedtls_mpi H, G, L;
|
||||
|
||||
if( f_rng == NULL || nbits < 128 || exponent < 3 )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
@ -512,10 +512,12 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
|
|||
|
||||
mbedtls_mpi_init( &H );
|
||||
mbedtls_mpi_init( &G );
|
||||
mbedtls_mpi_init( &L );
|
||||
|
||||
/*
|
||||
* find primes P and Q with Q < P so that:
|
||||
* GCD( E, (P-1)*(Q-1) ) == 1
|
||||
* 1. GCD( E, (P-1)*(Q-1) ) == 1
|
||||
* 2. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 )
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
|
||||
|
||||
|
@ -541,9 +543,23 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
|
|||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
|
||||
|
||||
/* check GCD( E, (P-1)*(Q-1) ) == 1 */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
|
||||
if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
|
||||
continue;
|
||||
|
||||
/* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->P, &ctx->Q ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L, NULL, &H, &G ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &L ) );
|
||||
|
||||
if( mbedtls_mpi_bitlen( &ctx->D ) <= ( ( nbits + 1 ) / 2 ) ) // (FIPS 186-4 §B.3.1 criterion 3(a))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 );
|
||||
while( 1 );
|
||||
|
||||
/* Restore P,Q */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
|
||||
|
@ -551,16 +567,12 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
|
|||
|
||||
ctx->len = mbedtls_mpi_size( &ctx->N );
|
||||
|
||||
#if !defined(MBEDTLS_RSA_NO_CRT)
|
||||
/*
|
||||
* D = E^-1 mod ((P-1)*(Q-1))
|
||||
* DP = D mod (P - 1)
|
||||
* DQ = D mod (Q - 1)
|
||||
* QP = Q^-1 mod P
|
||||
*/
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &H ) );
|
||||
|
||||
#if !defined(MBEDTLS_RSA_NO_CRT)
|
||||
MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
|
||||
&ctx->DP, &ctx->DQ, &ctx->QP ) );
|
||||
#endif /* MBEDTLS_RSA_NO_CRT */
|
||||
|
@ -572,6 +584,7 @@ cleanup:
|
|||
|
||||
mbedtls_mpi_free( &H );
|
||||
mbedtls_mpi_free( &G );
|
||||
mbedtls_mpi_free( &L );
|
||||
|
||||
if( ret != 0 )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue