Merge remote-tracking branch 'public/pr/1888' into mbedtls-2.7
diff --git a/ChangeLog b/ChangeLog
index 35324cf..a79b85d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,11 +1,32 @@
mbed TLS ChangeLog (Sorted per branch, date)
-= mbed TLS 2.7.6 branch released xxxx-xx-xx
+= mbed TLS x.x.x branch released xxxx-xx-xx
Bugfix
+ * Fixes an issue with MBEDTLS_CHACHAPOLY_C which would not compile if
+ MBEDTLS_ARC4_C and MBEDTLS_CIPHER_NULL_CIPHER weren't also defined. #1890
+ * Fix a memory leak in ecp_mul_comb() if ecp_precompute_comb() fails.
+ Fix contributed by Espressif Systems.
+ * Add ecc extensions only if an ecc based ciphersuite is used.
+ This improves compliance to RFC 4492, and as a result, solves
+ interoperability issues with BouncyCastle. Raised by milenamil in #1157.
+ * Fix potential use-after-free in mbedtls_ssl_get_max_frag_len()
+ and mbedtls_ssl_get_record_expansion() after a session reset. Fixes #1941.
+ * Fix a miscalculation of the maximum record expansion in
+ mbedtls_ssl_get_record_expansion() in case of CBC ciphersuites
+ in (D)TLS versions 1.1 or higher. Fixes #1914.
+ * Fix a bug that caused SSL/TLS clients to incorrectly abort the handshake
+ with TLS versions 1.1 and earlier when the server requested authentication
+ without providing a list of CAs. This was due to an overly strict bounds
+ check in parsing the CertificateRequest message,
+ introduced in Mbed TLS 2.12.0. Fixes #1954.
* Fix undefined shifts with negative values in certificates parsing
(found by Catena cyber using oss-fuzz)
+Changes
+ * Improve compatibility with some alternative CCM implementations by using
+ CCM test vectors from RAM.
+
= mbed TLS 2.7.5 branch released 2018-07-25
Security
diff --git a/library/ccm.c b/library/ccm.c
index 9101e5f..658f0d2 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -358,7 +358,8 @@
*/
#define NB_TESTS 3
-
+#define CCM_SELFTEST_PT_MAX_LEN 24
+#define CCM_SELFTEST_CT_MAX_LEN 32
/*
* The data is the same for all tests, only the used length changes
*/
@@ -378,7 +379,7 @@
0x10, 0x11, 0x12, 0x13
};
-static const unsigned char msg[] = {
+static const unsigned char msg[CCM_SELFTEST_PT_MAX_LEN] = {
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
@@ -389,7 +390,7 @@
static const size_t msg_len[NB_TESTS] = { 4, 16, 24 };
static const size_t tag_len[NB_TESTS] = { 4, 6, 8 };
-static const unsigned char res[NB_TESTS][32] = {
+static const unsigned char res[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = {
{ 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
{ 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
@@ -403,7 +404,13 @@
int mbedtls_ccm_self_test( int verbose )
{
mbedtls_ccm_context ctx;
- unsigned char out[32];
+ /*
+ * Some hardware accelerators require the input and output buffers
+ * would be in RAM, because the flash is not accessible.
+ * Use buffers on the stack to hold the test vectors data.
+ */
+ unsigned char plaintext[CCM_SELFTEST_PT_MAX_LEN];
+ unsigned char ciphertext[CCM_SELFTEST_CT_MAX_LEN];
size_t i;
int ret;
@@ -422,27 +429,32 @@
if( verbose != 0 )
mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 );
+ memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
+ memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN );
+ memcpy( plaintext, msg, msg_len[i] );
+
ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i],
- iv, iv_len[i], ad, add_len[i],
- msg, out,
- out + msg_len[i], tag_len[i] );
+ iv, iv_len[i], ad, add_len[i],
+ plaintext, ciphertext,
+ ciphertext + msg_len[i], tag_len[i] );
if( ret != 0 ||
- memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 )
+ memcmp( ciphertext, res[i], msg_len[i] + tag_len[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
+ memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i],
- iv, iv_len[i], ad, add_len[i],
- res[i], out,
- res[i] + msg_len[i], tag_len[i] );
+ iv, iv_len[i], ad, add_len[i],
+ ciphertext, plaintext,
+ ciphertext + msg_len[i], tag_len[i] );
if( ret != 0 ||
- memcmp( out, msg, msg_len[i] ) != 0 )
+ memcmp( plaintext, msg, msg_len[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
diff --git a/library/ecp.c b/library/ecp.c
index b41baef..213c2de 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -1448,7 +1448,12 @@
cleanup:
- if( T != NULL && ! p_eq_g )
+ /* There are two cases where T is not stored in grp:
+ * - P != G
+ * - An intermediate operation failed before setting grp->T
+ * In either case, T must be freed.
+ */
+ if( T != NULL && T != grp->T )
{
for( i = 0; i < pre_len; i++ )
mbedtls_ecp_point_free( &T[i] );
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
index 95e6163..800b5f8 100644
--- a/library/ssl_ciphersuites.c
+++ b/library/ssl_ciphersuites.c
@@ -1837,7 +1837,8 @@
#endif /* MBEDTLS_PK_C */
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
@@ -1847,13 +1848,14 @@
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+ case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
return( 1 );
default:
return( 0 );
}
}
-#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED*/
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info )
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 8b1db92..aaf42dd 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -769,6 +769,10 @@
unsigned char offer_compress;
const int *ciphersuites;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+ int uses_ec = 0;
+#endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
@@ -920,6 +924,11 @@
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
ciphersuites[i] ) );
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+ uses_ec |= mbedtls_ssl_ciphersuite_uses_ec( ciphersuite_info );
+#endif
+
n++;
*p++ = (unsigned char)( ciphersuites[i] >> 8 );
*p++ = (unsigned char)( ciphersuites[i] );
@@ -1013,11 +1022,14 @@
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
+ if( uses_ec )
+ {
+ ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
+ ext_len += olen;
- ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
+ ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
+ ext_len += olen;
+ }
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -2713,7 +2725,7 @@
* therefore the buffer length at this point must be greater than that
* regardless of the actual code path.
*/
- if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n )
+ if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index db45ca2..c8da871 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -2595,8 +2595,12 @@
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
+ if ( mbedtls_ssl_ciphersuite_uses_ec(
+ mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ) ) )
+ {
+ ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
+ ext_len += olen;
+ }
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index ca9b8c4..3b4dd8a 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -5911,7 +5911,11 @@
ssl->transform_in = NULL;
ssl->transform_out = NULL;
+ ssl->session_in = NULL;
+ ssl->session_out = NULL;
+
memset( ssl->out_buf, 0, MBEDTLS_SSL_BUFFER_LEN );
+
if( partial == 0 )
memset( ssl->in_buf, 0, MBEDTLS_SSL_BUFFER_LEN );
@@ -6684,17 +6688,18 @@
int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
{
- size_t transform_expansion;
+ size_t transform_expansion = 0;
const mbedtls_ssl_transform *transform = ssl->transform_out;
+ unsigned block_size;
+
+ if( transform == NULL )
+ return( (int) mbedtls_ssl_hdr_len( ssl ) );
#if defined(MBEDTLS_ZLIB_SUPPORT)
if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
#endif
- if( transform == NULL )
- return( (int) mbedtls_ssl_hdr_len( ssl ) );
-
switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
{
case MBEDTLS_MODE_GCM:
@@ -6704,8 +6709,25 @@
break;
case MBEDTLS_MODE_CBC:
- transform_expansion = transform->maclen
- + mbedtls_cipher_get_block_size( &transform->cipher_ctx_enc );
+
+ block_size = mbedtls_cipher_get_block_size(
+ &transform->cipher_ctx_enc );
+
+ /* Expansion due to the addition of the MAC. */
+ transform_expansion += transform->maclen;
+
+ /* Expansion due to the addition of CBC padding;
+ * Theoretically up to 256 bytes, but we never use
+ * more than the block size of the underlying cipher. */
+ transform_expansion += block_size;
+
+ /* For TLS 1.1 or higher, an explicit IV is added
+ * after the record header. */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+ transform_expansion += block_size;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
+
break;
default:
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index 04f8910..7214dc2 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -351,9 +351,15 @@
int ret = 1, len;
int exit_code = MBEDTLS_EXIT_FAILURE;
mbedtls_net_context server_fd;
- unsigned char buf[1024];
#if defined(MBEDTLS_BASE64_C)
unsigned char base[1024];
+ /* buf is used as the destination buffer for printing base with the format:
+ * "%s\r\n". Hence, the size of buf should be at least the size of base
+ * plus 2 bytes for the \r and \n characters.
+ */
+ unsigned char buf[sizeof( base ) + 2];
+#else
+ unsigned char buf[1024];
#endif
char hostname[32];
const char *pers = "ssl_mail_client";
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index 26ab88a..71934cf 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -164,7 +164,7 @@
const char *issuer_key; /* filename of the issuer key file */
const char *subject_pwd; /* password for the subject key file */
const char *issuer_pwd; /* password for the issuer key file */
- const char *output_file; /* where to store the constructed key file */
+ const char *output_file; /* where to store the constructed CRT */
const char *subject_name; /* subject name for certificate */
const char *issuer_name; /* issuer name for certificate */
const char *not_before; /* validity period not before */
@@ -774,7 +774,7 @@
}
/*
- * 1.2. Writing the request
+ * 1.2. Writing the certificate
*/
mbedtls_printf( " . Writing the certificate..." );
fflush( stdout );
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index a70ace3..d3d1589 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -605,6 +605,9 @@
if [ "$PRESERVE_LOGS" -gt 0 ]; then
mv $SRV_OUT o-srv-${TESTS}.log
mv $CLI_OUT o-cli-${TESTS}.log
+ if [ -n "$PXY_CMD" ]; then
+ mv $PXY_OUT o-pxy-${TESTS}.log
+ fi
fi
rm -f $SRV_OUT $CLI_OUT $PXY_OUT
@@ -782,6 +785,22 @@
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - The server has no ciphersuites in common"
+# Test empty CA list in CertificateRequest in TLS 1.1 and earlier
+
+requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1
+run_test "CertificateRequest with empty CA list, TLS 1.1 (GnuTLS server)" \
+ "$G_SRV"\
+ "$P_CLI force_version=tls1_1" \
+ 0
+
+requires_gnutls
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1
+run_test "CertificateRequest with empty CA list, TLS 1.0 (GnuTLS server)" \
+ "$G_SRV"\
+ "$P_CLI force_version=tls1" \
+ 0
+
# Tests for SHA-1 support
requires_config_disabled MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
@@ -4117,6 +4136,56 @@
-c "16384 bytes written in 1 fragments" \
-s "Read from client: 16384 bytes read"
+# Tests for ECC extensions (rfc 4492)
+
+requires_config_enabled MBEDTLS_AES_C
+requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
+requires_config_enabled MBEDTLS_SHA256_C
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+run_test "Force a non ECC ciphersuite in the client side" \
+ "$P_SRV debug_level=3" \
+ "$P_CLI debug_level=3 force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA256" \
+ 0 \
+ -C "client hello, adding supported_elliptic_curves extension" \
+ -C "client hello, adding supported_point_formats extension" \
+ -S "found supported elliptic curves extension" \
+ -S "found supported point formats extension"
+
+requires_config_enabled MBEDTLS_AES_C
+requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
+requires_config_enabled MBEDTLS_SHA256_C
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+run_test "Force a non ECC ciphersuite in the server side" \
+ "$P_SRV debug_level=3 force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA256" \
+ "$P_CLI debug_level=3" \
+ 0 \
+ -C "found supported_point_formats extension" \
+ -S "server hello, supported_point_formats extension"
+
+requires_config_enabled MBEDTLS_AES_C
+requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
+requires_config_enabled MBEDTLS_SHA256_C
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+run_test "Force an ECC ciphersuite in the client side" \
+ "$P_SRV debug_level=3" \
+ "$P_CLI debug_level=3 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256" \
+ 0 \
+ -c "client hello, adding supported_elliptic_curves extension" \
+ -c "client hello, adding supported_point_formats extension" \
+ -s "found supported elliptic curves extension" \
+ -s "found supported point formats extension"
+
+requires_config_enabled MBEDTLS_AES_C
+requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
+requires_config_enabled MBEDTLS_SHA256_C
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+run_test "Force an ECC ciphersuite in the server side" \
+ "$P_SRV debug_level=3 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256" \
+ "$P_CLI debug_level=3" \
+ 0 \
+ -c "found supported_point_formats extension" \
+ -s "server hello, supported_point_formats extension"
+
# Tests for DTLS HelloVerifyRequest
run_test "DTLS cookie: enabled" \
diff --git a/tests/suites/test_suite_pkparse.data b/tests/suites/test_suite_pkparse.data
index acd2cd9..5ffb580 100644
--- a/tests/suites/test_suite_pkparse.data
+++ b/tests/suites/test_suite_pkparse.data
@@ -207,15 +207,15 @@
pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbe_sha1_4096_rc4_128.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
Parse RSA Key #35 (PKCS#8 encrypted SHA1-RC4-128 DER)
-depends_on:MBEDTLS_DES_C:MBEDTLS_SHA1_C:MBEDTLS_PKCS12_C:MBEDTLS_CIPHER_MODE_CBC
+depends_on:MBEDTLS_ARC4_C:MBEDTLS_SHA1_C:MBEDTLS_PKCS12_C:MBEDTLS_CIPHER_MODE_CBC
pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbe_sha1_1024_rc4_128.der":"PolarSSLTest":0
Parse RSA Key #36 (PKCS#8 encrypted SHA1-RC4-128 DER, 2048-bit)
-depends_on:MBEDTLS_DES_C:MBEDTLS_SHA1_C:MBEDTLS_PKCS12_C:MBEDTLS_CIPHER_MODE_CBC
+depends_on:MBEDTLS_ARC4_C:MBEDTLS_SHA1_C:MBEDTLS_PKCS12_C:MBEDTLS_CIPHER_MODE_CBC
pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbe_sha1_2048_rc4_128.der":"PolarSSLTest":0
Parse RSA Key #37 (PKCS#8 encrypted SHA1-RC4-128 DER, 4096-bit)
-depends_on:MBEDTLS_DES_C:MBEDTLS_SHA1_C:MBEDTLS_PKCS12_C:MBEDTLS_CIPHER_MODE_CBC
+depends_on:MBEDTLS_ARC4_C:MBEDTLS_SHA1_C:MBEDTLS_PKCS12_C:MBEDTLS_CIPHER_MODE_CBC
pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbe_sha1_4096_rc4_128.der":"PolarSSLTest":0
Parse RSA Key #38 (PKCS#8 encrypted v2 PBKDF2 3DES)
@@ -1023,11 +1023,11 @@
pk_parse_keyfile_ec:"data_files/ec_prv.pk8param.pem":"NULL":0
Parse EC Key #6 (PKCS8 encrypted DER)
-depends_on:MBEDTLS_DES_C:MBEDTLS_SHA1_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED
+depends_on:MBEDTLS_ARC4_C:MBEDTLS_SHA1_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED
pk_parse_keyfile_ec:"data_files/ec_prv.pk8.pw.der":"polar":0
Parse EC Key #7 (PKCS8 encrypted PEM)
-depends_on:MBEDTLS_DES_C:MBEDTLS_SHA1_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED
+depends_on:MBEDTLS_ARC4_C:MBEDTLS_SHA1_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED
pk_parse_keyfile_ec:"data_files/ec_prv.pk8.pw.pem":"polar":0
Parse EC Key #8 (SEC1 PEM, secp224r1)