mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2025-01-08 22:55:33 +00:00
Merge remote-tracking branch 'public/pr/1380' into development-proposed
* public/pr/1380: Update ChangeLog for #1380 Generate RSA keys according to FIPS 186-4 Generate primes according to FIPS 186-4 Avoid small private exponents during RSA key generation
This commit is contained in:
commit
64f5adf9f9
|
@ -42,7 +42,7 @@ Bugfix
|
|||
mnacamura.
|
||||
* Fix parsing of PKCS#8 encoded Elliptic Curve keys. Previously Mbed TLS was
|
||||
unable to parse keys with only the optional parameters field of the
|
||||
ECPrivateKey structure. Found by jethrogb, fixed in #1379.
|
||||
ECPrivateKey structure. Found by Jethro Beekman, fixed in #1379.
|
||||
* Return plaintext data sooner on unpadded CBC decryption, as stated in
|
||||
the mbedtls_cipher_update() documentation. Contributed by Andy Leiserson.
|
||||
* Fix overriding and ignoring return values when parsing and writing to
|
||||
|
@ -93,6 +93,8 @@ Changes
|
|||
* Improve robustness of mbedtls_ssl_derive_keys against the use of
|
||||
HMAC functions with non-HMAC ciphersuites. Independently contributed
|
||||
by Jiayuan Chen in #1377. Fixes #1437.
|
||||
* Improve security of RSA key generation by including criteria from FIPS
|
||||
186-4. Contributed by Jethro Beekman. #1380
|
||||
|
||||
= mbed TLS 2.8.0 branch released 2018-03-16
|
||||
|
||||
|
|
116
library/bignum.c
116
library/bignum.c
|
@ -2194,12 +2194,23 @@ int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
|
|||
|
||||
/*
|
||||
* Prime number generation
|
||||
*
|
||||
* If dh_flag is 0 and nbits is at least 1024, then the procedure
|
||||
* follows the RSA probably-prime generation method of FIPS 186-4.
|
||||
* NB. FIPS 186-4 only allows the specific bit lengths of 1024 and 1536.
|
||||
*/
|
||||
int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret;
|
||||
#ifdef MBEDTLS_HAVE_INT64
|
||||
// ceil(2^63.5)
|
||||
#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
|
||||
#else
|
||||
// ceil(2^31.5)
|
||||
#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
|
||||
#endif
|
||||
int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
|
||||
size_t k, n;
|
||||
mbedtls_mpi_uint r;
|
||||
mbedtls_mpi Y;
|
||||
|
@ -2211,69 +2222,66 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
|
|||
|
||||
n = BITS_TO_LIMBS( nbits );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
|
||||
|
||||
k = mbedtls_mpi_bitlen( X );
|
||||
if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits + 1 ) );
|
||||
|
||||
mbedtls_mpi_set_bit( X, nbits-1, 1 );
|
||||
|
||||
X->p[0] |= 1;
|
||||
|
||||
if( dh_flag == 0 )
|
||||
while( 1 )
|
||||
{
|
||||
while( ( ret = mbedtls_mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
|
||||
/* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
|
||||
if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue;
|
||||
|
||||
k = n * biL;
|
||||
if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) );
|
||||
X->p[0] |= 1;
|
||||
|
||||
if( dh_flag == 0 )
|
||||
{
|
||||
ret = mbedtls_mpi_is_prime( X, f_rng, p_rng );
|
||||
|
||||
if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
|
||||
goto cleanup;
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 2 ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* An necessary condition for Y and X = 2Y + 1 to be prime
|
||||
* is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
|
||||
* Make sure it is satisfied, while keeping X = 3 mod 4
|
||||
*/
|
||||
|
||||
X->p[0] |= 2;
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
|
||||
if( r == 0 )
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
|
||||
else if( r == 1 )
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
|
||||
|
||||
/* Set Y = (X-1) / 2, which is X / 2 because X is odd */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
|
||||
|
||||
while( 1 )
|
||||
else
|
||||
{
|
||||
/*
|
||||
* First, check small factors for X and Y
|
||||
* before doing Miller-Rabin on any of them
|
||||
* An necessary condition for Y and X = 2Y + 1 to be prime
|
||||
* is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
|
||||
* Make sure it is satisfied, while keeping X = 3 mod 4
|
||||
*/
|
||||
if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
|
||||
( ret = mpi_check_small_factors( &Y ) ) == 0 &&
|
||||
( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
|
||||
( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
|
||||
|
||||
X->p[0] |= 2;
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
|
||||
if( r == 0 )
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
|
||||
else if( r == 1 )
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
|
||||
|
||||
/* Set Y = (X-1) / 2, which is X / 2 because X is odd */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
break;
|
||||
/*
|
||||
* First, check small factors for X and Y
|
||||
* before doing Miller-Rabin on any of them
|
||||
*/
|
||||
if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
|
||||
( ret = mpi_check_small_factors( &Y ) ) == 0 &&
|
||||
( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
|
||||
( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
|
||||
goto cleanup;
|
||||
|
||||
if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
|
||||
goto cleanup;
|
||||
|
||||
/*
|
||||
* Next candidates. We want to preserve Y = (X-1) / 2 and
|
||||
* Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
|
||||
* so up Y by 6 and X by 12.
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) );
|
||||
}
|
||||
|
||||
if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
|
||||
goto cleanup;
|
||||
|
||||
/*
|
||||
* Next candidates. We want to preserve Y = (X-1) / 2 and
|
||||
* Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
|
||||
* so up Y by 6 and X by 12.
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -495,6 +495,9 @@ size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
|
|||
|
||||
/*
|
||||
* Generate an RSA keypair
|
||||
*
|
||||
* This generation method follows the RSA key pair generation procedure of
|
||||
* FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072.
|
||||
*/
|
||||
int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
|
@ -502,7 +505,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 +515,13 @@ 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. |P-Q| > 2^( nbits / 2 - 100 )
|
||||
* 2. GCD( E, (P-1)*(Q-1) ) == 1
|
||||
* 3. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 )
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
|
||||
|
||||
|
@ -527,40 +533,51 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
|
|||
MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
|
||||
f_rng, p_rng ) );
|
||||
|
||||
if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
|
||||
/* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &H, &ctx->P, &ctx->Q ) );
|
||||
if( mbedtls_mpi_bitlen( &H ) <= ( ( nbits >= 200 ) ? ( ( nbits >> 1 ) - 99 ) : 0 ) )
|
||||
continue;
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
|
||||
if( mbedtls_mpi_bitlen( &ctx->N ) != nbits )
|
||||
continue;
|
||||
|
||||
if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
|
||||
/* not required by any standards, but some users rely on the fact that P > Q */
|
||||
if( H.s < 0 )
|
||||
mbedtls_mpi_swap( &ctx->P, &ctx->Q );
|
||||
|
||||
/* Temporarily replace P,Q by P-1, Q-1 */
|
||||
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 (FIPS 186-4 §B.3.1 criterion 2(a)) */
|
||||
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) (FIPS 186-4 §B.3.1 criterion 3(b)) */
|
||||
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 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
|
||||
|
||||
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 +589,7 @@ cleanup:
|
|||
|
||||
mbedtls_mpi_free( &H );
|
||||
mbedtls_mpi_free( &G );
|
||||
mbedtls_mpi_free( &L );
|
||||
|
||||
if( ret != 0 )
|
||||
{
|
||||
|
|
|
@ -688,6 +688,18 @@ Test mbedtls_mpi_gen_prime (OK, minimum size)
|
|||
depends_on:MBEDTLS_GENPRIME
|
||||
mbedtls_mpi_gen_prime:3:0:0
|
||||
|
||||
Test mbedtls_mpi_gen_prime (corner case limb size -1 bits)
|
||||
depends_on:MBEDTLS_GENPRIME
|
||||
mbedtls_mpi_gen_prime:63:0:0
|
||||
|
||||
Test mbedtls_mpi_gen_prime (corner case limb size)
|
||||
depends_on:MBEDTLS_GENPRIME
|
||||
mbedtls_mpi_gen_prime:64:0:0
|
||||
|
||||
Test mbedtls_mpi_gen_prime (corner case limb size +1 bits)
|
||||
depends_on:MBEDTLS_GENPRIME
|
||||
mbedtls_mpi_gen_prime:65:0:0
|
||||
|
||||
Test mbedtls_mpi_gen_prime (Larger)
|
||||
depends_on:MBEDTLS_GENPRIME
|
||||
mbedtls_mpi_gen_prime:128:0:0
|
||||
|
|
Loading…
Reference in a new issue