Merge branch 'mbedtls-2.7-proposed' into mbedtls-2.7-restricted-proposed
diff --git a/ChangeLog b/ChangeLog
index 5c8af69..e2357ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,14 @@
= mbed TLS x.x.x branch released xxxx-xx-xx
+Security
+ * Verify results of RSA private key operations to defend
+ against Bellcore glitch attack.
+ * Fix a buffer overread in ssl_parse_server_key_exchange() that could cause
+ a crash on invalid input.
+ * Fix a buffer overread in ssl_parse_server_psk_hint() that could cause a
+ crash on invalid input.
+
Features
* Extend PKCS#8 interface by introducing support for the entire SHA
algorithms family when encrypting private keys using PKCS#5 v2.0.
@@ -21,6 +29,8 @@
overflow. #1179
* Fix memory allocation corner cases in memory_buffer_alloc.c module. Found
by Guido Vranken. #639
+ * Fix X509 CRT parsing that would potentially accept an invalid tag when
+ parsing the subject alternative names.
* Fix a possible arithmetic overflow in ssl_parse_server_key_exchange()
that could cause a key exchange to fail on valid data.
* Fix a possible arithmetic overflow in ssl_parse_server_psk_hint() that
@@ -112,10 +122,6 @@
* Change default choice of DHE parameters from untrustworthy RFC 5114
to RFC 3526 containing parameters generated in a nothing-up-my-sleeve
manner.
- * Fix a buffer overread in ssl_parse_server_key_exchange() that could cause
- a crash on invalid input.
- * Fix a buffer overread in ssl_parse_server_psk_hint() that could cause a
- crash on invalid input.
Features
* Allow comments in test data files.
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index fde328a..96c1c9a 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -88,6 +88,21 @@
#define MBEDTLS_ASN1_PRIMITIVE 0x00
#define MBEDTLS_ASN1_CONSTRUCTED 0x20
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80
+
+/*
+ * Bit masks for each of the components of an ASN.1 tag as specified in
+ * ITU X.690 (08/2015), section 8.1 "General rules for encoding",
+ * paragraph 8.1.2.2:
+ *
+ * Bit 8 7 6 5 1
+ * +-------+-----+------------+
+ * | Class | P/C | Tag number |
+ * +-------+-----+------------+
+ */
+#define MBEDTLS_ASN1_TAG_CLASS_MASK 0xC0
+#define MBEDTLS_ASN1_TAG_PC_MASK 0x20
+#define MBEDTLS_ASN1_TAG_VALUE_MASK 0x1F
+
/* \} name */
/* \} addtogroup asn1_module */
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 1c98558..c7ba174 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1049,7 +1049,8 @@
/**
* \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.
*
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index fb2f77f..5548f3c 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -518,6 +518,18 @@
*
* \note The input and output buffers must be large
* 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 (*f_rng)(void *, unsigned char *, size_t),
diff --git a/library/bignum.c b/library/bignum.c
index d27c130..9f13da4 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -1623,7 +1623,7 @@
mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
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 );
if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
diff --git a/library/rsa.c b/library/rsa.c
index 6526978..c9f7ba9 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -773,16 +773,38 @@
{
int ret;
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;
-#if defined(MBEDTLS_RSA_NO_CRT)
- mbedtls_mpi D_blind;
- mbedtls_mpi *D = &ctx->D;
-#else
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+ /* Temporaries holding the results mod p resp. mod q. */
+ 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;
+
+ /* 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 *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 */,
f_rng != NULL /* blinding y/n */ ) != 0 )
@@ -790,8 +812,17 @@
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
}
- mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
- mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &R );
+#if defined(MBEDTLS_THREADING_C)
+ 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 )
{
@@ -803,12 +834,15 @@
#endif
}
-
-#if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( ret );
+#if !defined(MBEDTLS_RSA_NO_CRT)
+ mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ );
#endif
+ mbedtls_mpi_init( &I );
+ mbedtls_mpi_init( &C );
+
+ /* End of MPI initialization */
+
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
{
@@ -816,6 +850,8 @@
goto cleanup;
}
+ MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) );
+
if( f_rng != NULL )
{
/*
@@ -874,24 +910,25 @@
/*
* Faster decryption using the CRT
*
- * T1 = input ^ dP mod P
- * T2 = input ^ dQ mod Q
+ * TP = input ^ dP mod P
+ * 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_mul_mpi( &T1, &T, &ctx->QP ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &TP, &TQ ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->QP ) );
+ 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_add_mpi( &T, &T2, &T1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->Q ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) );
#endif /* MBEDTLS_RSA_NO_CRT */
if( f_rng != NULL )
@@ -904,6 +941,15 @@
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;
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
@@ -913,8 +959,9 @@
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
- mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
- mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &R );
+ mbedtls_mpi_free( &P1 );
+ mbedtls_mpi_free( &Q1 );
+ mbedtls_mpi_free( &R );
if( f_rng != NULL )
{
@@ -926,6 +973,15 @@
#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 )
return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
@@ -2222,7 +2278,8 @@
if( verbose != 0 )
mbedtls_printf( "failed\n" );
- return( 1 );
+ ret = 1;
+ goto cleanup;
}
if( verbose != 0 )
@@ -2237,7 +2294,8 @@
if( verbose != 0 )
mbedtls_printf( "failed\n" );
- return( 1 );
+ ret = 1;
+ goto cleanup;
}
if( verbose != 0 )
@@ -2250,7 +2308,8 @@
if( verbose != 0 )
mbedtls_printf( "failed\n" );
- return( 1 );
+ ret = 1;
+ goto cleanup;
}
if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
@@ -2258,7 +2317,8 @@
if( verbose != 0 )
mbedtls_printf( "failed\n" );
- return( 1 );
+ ret = 1;
+ goto cleanup;
}
if( verbose != 0 )
@@ -2283,7 +2343,8 @@
if( verbose != 0 )
mbedtls_printf( "failed\n" );
- return( 1 );
+ ret = 1;
+ goto cleanup;
}
if( verbose != 0 )
@@ -2296,7 +2357,8 @@
if( verbose != 0 )
mbedtls_printf( "failed\n" );
- return( 1 );
+ ret = 1;
+ goto cleanup;
}
if( verbose != 0 )
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 0e28dac..daa3163 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -473,9 +473,12 @@
if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 )
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- if( ( tag & MBEDTLS_ASN1_CONTEXT_SPECIFIC ) != MBEDTLS_ASN1_CONTEXT_SPECIFIC )
+ if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) !=
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC )
+ {
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ }
/* Skip everything but DNS name */
if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) )
diff --git a/scripts/config.pl b/scripts/config.pl
index 76ca470..5bf2785 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -17,7 +17,7 @@
#
# 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_DEPRECATED_REMOVED
@@ -30,6 +30,7 @@
# MBEDTLS_NO_PLATFORM_ENTROPY
# MBEDTLS_REMOVE_ARC4_CIPHERSUITES
# MBEDTLS_SSL_HW_RECORD_ACCEL
+# MBEDTLS_RSA_NO_CRT
# MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
# MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
# - this could be enabled if the respective tests were adapted
@@ -86,6 +87,7 @@
MBEDTLS_ECP_DP_M511_ENABLED
MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
MBEDTLS_NO_PLATFORM_ENTROPY
+MBEDTLS_RSA_NO_CRT
MBEDTLS_REMOVE_ARC4_CIPHERSUITES
MBEDTLS_SSL_HW_RECORD_ACCEL
MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 67b22cd..fdb99be 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -530,6 +530,22 @@
msg "test: !MBEDTLS_SSL_RENEGOTIATION - ssl-opt.sh (ASan build)" # ~ 6 min
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
cleanup
cp "$CONFIG_H" "$CONFIG_BAK"
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 421227f..c0c987d 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -43,15 +43,18 @@
const unsigned char *input, unsigned char *output,
size_t output_max_len )
{
- return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, NULL, NULL, mode, olen,
- input, output, output_max_len ) );
+ return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx,
+ rnd_std_rand, NULL, mode, olen,
+ input, output, output_max_len ) );
}
int mbedtls_rsa_sign_func( void *ctx,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
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 ) );
}
size_t mbedtls_rsa_key_len_func( void *ctx )
@@ -105,7 +108,8 @@
if( mbedtls_pk_get_type( &prv ) == MBEDTLS_PK_RSA )
{
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 );
}
#endif
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 73ccead..8e17163 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -1144,6 +1144,10 @@
X509 Certificate ASN1 (invalid version overflow)
x509parse_crt:"301A3018a00602047FFFFFFF8204deadbeef30080604cafed00d0500":"":MBEDTLS_ERR_X509_UNKNOWN_VERSION
+X509 Certificate ASN1 (invalid SubjectAltNames tag)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
+x509parse_crt:"308203723082025AA003020102020111300D06092A864886F70D0101050500303B310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C3119301706035504031310506F6C617253534C2054657374204341301E170D3132303531303133323334315A170D3232303531313133323334315A303A310B3009060355040613024E4C3111300F060355040A1308506F6C617253534C311830160603550403130F7777772E6578616D706C652E636F6D30820122300D06092A864886F70D01010105000382010F003082010A0282010100B93C4AC5C8A38E9017A49E52AA7175266180E7C7B56D8CFFAAB64126B7BE11AD5C73160C64114804FFD6E13B05DB89BBB39709D51C14DD688739B03D71CBE276D01AD8182D801B54F6E5449AF1CBAF612EDF490D9D09B7EDB1FD3CFD3CFA24CF5DBF7CE453E725B5EA4422E926D3EA20949EE66167BA2E07670B032FA209EDF0338F0BCE10EF67A4C608DAC1EDC23FD74ADD153DF95E1C8160463EB5B33D2FA6DE471CBC92AEEBDF276B1656B7DCECD15557A56EEC7525F5B77BDFABD23A5A91987D97170B130AA76B4A8BC14730FB3AF84104D5C1DFB81DBF7B01A565A2E01E36B7A65CCC305AF8CD6FCDF1196225CA01E3357FFA20F5DCFD69B26A007D17F70203010001A38181307F30090603551D1304023000301D0603551D0E041604147DE49C6BE6F9717D46D2123DAD6B1DFDC2AA784C301F0603551D23041830168014B45AE4A5B3DED252F6B9D5A6950FEB3EBCC7FDFF30320603551D11042B3029C20B6578616D706C652E636F6D820B6578616D706C652E6E6574820D2A2E6578616D706C652E6F7267300D06092A864886F70D010105050003820101004F09CB7AD5EEF5EF620DDC7BA285D68CCA95B46BDA115B92007513B9CA0BCEEAFBC31FE23F7F217479E2E6BCDA06E52F6FF655C67339CF48BC0D2F0CD27A06C34A4CD9485DA0D07389E4D4851D969A0E5799C66F1D21271F8D0529E840AE823968C39707CF3C934C1ADF2FA6A455487F7C8C1AC922DA24CD9239C68AECB08DF5698267CB04EEDE534196C127DC2FFE33FAD30EB8D432A9842853A5F0D189D5A298E71691BB9CC0418E8C58ACFFE3DD2E7AABB0B97176AD0F2733F7A929D3C076C0BF06407C0ED5A47C8AE2326E16AEDA641FB0557CDBDDF1A4BA447CB39958D2346E00EA976C143AF2101E0AA249107601F4F2C818FDCC6346128B091BF194E6":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
X509 CRL ASN1 (Incorrect first tag)
x509parse_crl:"":"":MBEDTLS_ERR_X509_INVALID_FORMAT