Merge remote-tracking branch 'upstream-restricted/pr/351' into development-restricted-proposed

Move the added ChangeLog entry to the bottom so that the list remains
in merge order.
This commit is contained in:
Gilles Peskine 2018-03-13 17:15:34 +01:00
commit 553a06f08a
8 changed files with 137 additions and 38 deletions

View file

@ -17,6 +17,8 @@ Security
implementation allowed an offline 2^80 brute force attack on the implementation allowed an offline 2^80 brute force attack on the
HMAC key of a single, uninterrupted connection (with no HMAC key of a single, uninterrupted connection (with no
resumption of the session). resumption of the session).
* Verify results of RSA private key operations to defend
against Bellcore glitch attack.
Features Features
* Extend PKCS#8 interface by introducing support for the entire SHA * Extend PKCS#8 interface by introducing support for the entire SHA

View file

@ -1049,7 +1049,8 @@
/** /**
* \def MBEDTLS_RSA_NO_CRT * \def MBEDTLS_RSA_NO_CRT
* *
* Do not use the Chinese Remainder Theorem for the RSA private operation. * Do not use the Chinese Remainder Theorem
* for the RSA private operation.
* *
* Uncomment this macro to disable the use of CRT in RSA. * Uncomment this macro to disable the use of CRT in RSA.
* *

View file

@ -518,6 +518,18 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
* *
* \note The input and output buffers must be large * \note The input and output buffers must be large
* enough. For example, 128 Bytes if RSA-1024 is used. * enough. For example, 128 Bytes if RSA-1024 is used.
*
* \note Blinding is used if and only if a PRNG is provided.
*
* \note If blinding is used, both the base of exponentation
* and the exponent are blinded, providing protection
* against some side-channel attacks.
*
* \warning It is deprecated and a security risk to not provide
* a PRNG here and thereby prevent the use of blinding.
* Future versions of the library may enforce the presence
* of a PRNG.
*
*/ */
int mbedtls_rsa_private( mbedtls_rsa_context *ctx, int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t), int (*f_rng)(void *, unsigned char *, size_t),

View file

@ -1623,7 +1623,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos; mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
int neg; int neg;
if( mbedtls_mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 ) if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
if( mbedtls_mpi_cmp_int( E, 0 ) < 0 ) if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )

View file

@ -773,16 +773,38 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
{ {
int ret; int ret;
size_t olen; size_t olen;
mbedtls_mpi T, T1, T2;
/* Temporary holding the result */
mbedtls_mpi T;
/* Temporaries holding P-1, Q-1 and the
* exponent blinding factor, respectively. */
mbedtls_mpi P1, Q1, R; mbedtls_mpi P1, Q1, R;
#if defined(MBEDTLS_RSA_NO_CRT)
mbedtls_mpi D_blind; #if !defined(MBEDTLS_RSA_NO_CRT)
mbedtls_mpi *D = &ctx->D; /* Temporaries holding the results mod p resp. mod q. */
#else mbedtls_mpi TP, TQ;
/* Temporaries holding the blinded exponents for
* the mod p resp. mod q computation (if used). */
mbedtls_mpi DP_blind, DQ_blind; mbedtls_mpi DP_blind, DQ_blind;
/* Pointers to actual exponents to be used - either the unblinded
* or the blinded ones, depending on the presence of a PRNG. */
mbedtls_mpi *DP = &ctx->DP; mbedtls_mpi *DP = &ctx->DP;
mbedtls_mpi *DQ = &ctx->DQ; mbedtls_mpi *DQ = &ctx->DQ;
#endif #else
/* Temporary holding the blinded exponent (if used). */
mbedtls_mpi D_blind;
/* Pointer to actual exponent to be used - either the unblinded
* or the blinded one, depending on the presence of a PRNG. */
mbedtls_mpi *D = &ctx->D;
#endif /* MBEDTLS_RSA_NO_CRT */
/* Temporaries holding the initial input and the double
* checked result; should be the same in the end. */
mbedtls_mpi I, C;
if( rsa_check_context( ctx, 1 /* private key checks */, if( rsa_check_context( ctx, 1 /* private key checks */,
f_rng != NULL /* blinding y/n */ ) != 0 ) f_rng != NULL /* blinding y/n */ ) != 0 )
@ -790,8 +812,17 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
} }
mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); #if defined(MBEDTLS_THREADING_C)
mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &R ); if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
return( ret );
#endif
/* MPI Initialization */
mbedtls_mpi_init( &T );
mbedtls_mpi_init( &P1 );
mbedtls_mpi_init( &Q1 );
mbedtls_mpi_init( &R );
if( f_rng != NULL ) if( f_rng != NULL )
{ {
@ -803,12 +834,15 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
#endif #endif
} }
#if !defined(MBEDTLS_RSA_NO_CRT)
#if defined(MBEDTLS_THREADING_C) mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ );
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
return( ret );
#endif #endif
mbedtls_mpi_init( &I );
mbedtls_mpi_init( &C );
/* End of MPI initialization */
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
{ {
@ -816,6 +850,8 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
goto cleanup; goto cleanup;
} }
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) );
if( f_rng != NULL ) if( f_rng != NULL )
{ {
/* /*
@ -874,24 +910,25 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
/* /*
* Faster decryption using the CRT * Faster decryption using the CRT
* *
* T1 = input ^ dP mod P * TP = input ^ dP mod P
* T2 = input ^ dQ mod Q * TQ = input ^ dQ mod Q
*/ */
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, DP, &ctx->P, &ctx->RP ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, DQ, &ctx->Q, &ctx->RQ ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TP, &T, DP, &ctx->P, &ctx->RP ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TQ, &T, DQ, &ctx->Q, &ctx->RQ ) );
/* /*
* T = (T1 - T2) * (Q^-1 mod P) mod P * T = (TP - TQ) * (Q^-1 mod P) mod P
*/ */
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &TP, &TQ ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->QP ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &TP, &ctx->P ) );
/* /*
* T = T2 + T * Q * T = TQ + T * Q
*/ */
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->Q ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) );
#endif /* MBEDTLS_RSA_NO_CRT */ #endif /* MBEDTLS_RSA_NO_CRT */
if( f_rng != NULL ) if( f_rng != NULL )
@ -904,6 +941,15 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
} }
/* Verify the result to prevent glitching attacks. */
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &C, &T, &ctx->E,
&ctx->N, &ctx->RN ) );
if( mbedtls_mpi_cmp_mpi( &C, &I ) != 0 )
{
ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
goto cleanup;
}
olen = ctx->len; olen = ctx->len;
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
@ -913,8 +959,9 @@ cleanup:
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif #endif
mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); mbedtls_mpi_free( &P1 );
mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &Q1 );
mbedtls_mpi_free( &R );
if( f_rng != NULL ) if( f_rng != NULL )
{ {
@ -926,6 +973,15 @@ cleanup:
#endif #endif
} }
mbedtls_mpi_free( &T );
#if !defined(MBEDTLS_RSA_NO_CRT)
mbedtls_mpi_free( &TP ); mbedtls_mpi_free( &TQ );
#endif
mbedtls_mpi_free( &C );
mbedtls_mpi_free( &I );
if( ret != 0 ) if( ret != 0 )
return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret ); return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
@ -2222,7 +2278,8 @@ int mbedtls_rsa_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "failed\n" ); mbedtls_printf( "failed\n" );
return( 1 ); ret = 1;
goto cleanup;
} }
if( verbose != 0 ) if( verbose != 0 )
@ -2237,7 +2294,8 @@ int mbedtls_rsa_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "failed\n" ); mbedtls_printf( "failed\n" );
return( 1 ); ret = 1;
goto cleanup;
} }
if( verbose != 0 ) if( verbose != 0 )
@ -2250,7 +2308,8 @@ int mbedtls_rsa_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "failed\n" ); mbedtls_printf( "failed\n" );
return( 1 ); ret = 1;
goto cleanup;
} }
if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
@ -2258,7 +2317,8 @@ int mbedtls_rsa_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "failed\n" ); mbedtls_printf( "failed\n" );
return( 1 ); ret = 1;
goto cleanup;
} }
if( verbose != 0 ) if( verbose != 0 )
@ -2283,7 +2343,8 @@ int mbedtls_rsa_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "failed\n" ); mbedtls_printf( "failed\n" );
return( 1 ); ret = 1;
goto cleanup;
} }
if( verbose != 0 ) if( verbose != 0 )
@ -2296,7 +2357,8 @@ int mbedtls_rsa_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "failed\n" ); mbedtls_printf( "failed\n" );
return( 1 ); ret = 1;
goto cleanup;
} }
if( verbose != 0 ) if( verbose != 0 )

View file

@ -17,7 +17,7 @@
# #
# Full usage description provided below. # Full usage description provided below.
# #
# Things that shouldn't be enabled with "full". # The following options are disabled instead of enabled with "full".
# #
# MBEDTLS_TEST_NULL_ENTROPY # MBEDTLS_TEST_NULL_ENTROPY
# MBEDTLS_DEPRECATED_REMOVED # MBEDTLS_DEPRECATED_REMOVED
@ -30,6 +30,7 @@
# MBEDTLS_NO_PLATFORM_ENTROPY # MBEDTLS_NO_PLATFORM_ENTROPY
# MBEDTLS_REMOVE_ARC4_CIPHERSUITES # MBEDTLS_REMOVE_ARC4_CIPHERSUITES
# MBEDTLS_SSL_HW_RECORD_ACCEL # MBEDTLS_SSL_HW_RECORD_ACCEL
# MBEDTLS_RSA_NO_CRT
# MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 # MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
# MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION # MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
# - this could be enabled if the respective tests were adapted # - this could be enabled if the respective tests were adapted
@ -86,6 +87,7 @@ MBEDTLS_ECP_DP_M383_ENABLED
MBEDTLS_ECP_DP_M511_ENABLED MBEDTLS_ECP_DP_M511_ENABLED
MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
MBEDTLS_NO_PLATFORM_ENTROPY MBEDTLS_NO_PLATFORM_ENTROPY
MBEDTLS_RSA_NO_CRT
MBEDTLS_REMOVE_ARC4_CIPHERSUITES MBEDTLS_REMOVE_ARC4_CIPHERSUITES
MBEDTLS_SSL_HW_RECORD_ACCEL MBEDTLS_SSL_HW_RECORD_ACCEL
MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3

View file

@ -530,6 +530,22 @@ make test
msg "test: !MBEDTLS_SSL_RENEGOTIATION - ssl-opt.sh (ASan build)" # ~ 6 min msg "test: !MBEDTLS_SSL_RENEGOTIATION - ssl-opt.sh (ASan build)" # ~ 6 min
if_build_succeeded tests/ssl-opt.sh if_build_succeeded tests/ssl-opt.sh
msg "build: Default + RSA_NO_CRT (ASan build)" # ~ 6 min
cleanup
cp "$CONFIG_H" "$CONFIG_BAK"
scripts/config.pl set MBEDTLS_RSA_NO_CRT
CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
make
msg "test: RSA_NO_CRT - main suites (inc. selftests) (ASan build)" # ~ 50s
make test
msg "test: RSA_NO_CRT - RSA-related part of ssl-opt.sh (ASan build)" # ~ 5s
tests/ssl-opt.sh -f RSA
msg "test: RSA_NO_CRT - RSA-related part of compat.sh (ASan build)" # ~ 3 min
tests/compat.sh -t RSA
msg "build: cmake, full config, clang, C99" # ~ 50s msg "build: cmake, full config, clang, C99" # ~ 50s
cleanup cleanup
cp "$CONFIG_H" "$CONFIG_BAK" cp "$CONFIG_H" "$CONFIG_BAK"

View file

@ -43,15 +43,18 @@ int mbedtls_rsa_decrypt_func( void *ctx, int mode, size_t *olen,
const unsigned char *input, unsigned char *output, const unsigned char *input, unsigned char *output,
size_t output_max_len ) size_t output_max_len )
{ {
return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, NULL, NULL, mode, olen, return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx,
input, output, output_max_len ) ); rnd_std_rand, NULL, mode, olen,
input, output, output_max_len ) );
} }
int mbedtls_rsa_sign_func( void *ctx, int mbedtls_rsa_sign_func( void *ctx,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
const unsigned char *hash, unsigned char *sig ) const unsigned char *hash, unsigned char *sig )
{ {
return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, mode, ((void) f_rng);
((void) p_rng);
return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, rnd_std_rand, NULL, mode,
md_alg, hashlen, hash, sig ) ); md_alg, hashlen, hash, sig ) );
} }
size_t mbedtls_rsa_key_len_func( void *ctx ) size_t mbedtls_rsa_key_len_func( void *ctx )
@ -105,7 +108,8 @@ void mbedtls_pk_check_pair( char *pub_file, char *prv_file, int ret )
if( mbedtls_pk_get_type( &prv ) == MBEDTLS_PK_RSA ) if( mbedtls_pk_get_type( &prv ) == MBEDTLS_PK_RSA )
{ {
TEST_ASSERT( mbedtls_pk_setup_rsa_alt( &alt, mbedtls_pk_rsa( prv ), TEST_ASSERT( mbedtls_pk_setup_rsa_alt( &alt, mbedtls_pk_rsa( prv ),
mbedtls_rsa_decrypt_func, mbedtls_rsa_sign_func, mbedtls_rsa_key_len_func ) == 0 ); mbedtls_rsa_decrypt_func, mbedtls_rsa_sign_func,
mbedtls_rsa_key_len_func ) == 0 );
TEST_ASSERT( mbedtls_pk_check_pair( &pub, &alt ) == ret ); TEST_ASSERT( mbedtls_pk_check_pair( &pub, &alt ) == ret );
} }
#endif #endif