Merge branch 'mbedtls-2.1'
diff --git a/ChangeLog b/ChangeLog
index d28d2c7..ac0e32a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,16 @@
mbed TLS ChangeLog (Sorted per branch, date)
-= mbed TLS 2.1.x
+= mbed TLS 2.1.x branch released 2016-xx-xx
+
+Security
+ * Remove MBEDTLS_SSL_AEAD_RANDOM_IV option, because it was not compliant
+ with RFC5116 and could lead to session key recovery in very long TLS
+ sessions. (H. Bock, A. Zauner, S. Devlin, J. Somorovsky, P. Jovanovic -
+ "Nonce-Disrespecting Adversaries Practical Forgery Attacks on GCM in TLS")
+ * Fix potential stack corruption in mbedtls_x509write_crt_der() and
+ mbedtls_x509write_csr_der() when the signature is copied to the buffer
+ without checking whether there is enough space in the destination. The
+ issue cannot be triggered remotely. (found by Jethro Beekman)
Bugfix
* Fix an issue that caused valid certificates being rejected whenever an
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 5147ec6..e77cf26 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -869,18 +869,6 @@
//#define MBEDTLS_SHA256_SMALLER
/**
- * \def MBEDTLS_SSL_AEAD_RANDOM_IV
- *
- * Generate a random IV rather than using the record sequence number as a
- * nonce for ciphersuites using and AEAD algorithm (GCM or CCM).
- *
- * Using the sequence number is generally recommended.
- *
- * Uncomment this macro to always use random IVs with AEAD ciphersuites.
- */
-//#define MBEDTLS_SSL_AEAD_RANDOM_IV
-
-/**
* \def MBEDTLS_SSL_ALL_ALERT_MESSAGES
*
* Enable sending of alert messages in case of encountered errors as per RFC.
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index bf60941..d442642 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1364,17 +1364,6 @@
/*
* Generate IV
*/
-#if defined(MBEDTLS_SSL_AEAD_RANDOM_IV)
- ret = ssl->conf->f_rng( ssl->conf->p_rng,
- ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
- ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
- if( ret != 0 )
- return( ret );
-
- memcpy( ssl->out_iv,
- ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
- ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
-#else
if( ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen != 8 )
{
/* Reminder if we ever add an AEAD mode with a different size */
@@ -1385,7 +1374,6 @@
memcpy( ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
ssl->out_ctr, 8 );
memcpy( ssl->out_iv, ssl->out_ctr, 8 );
-#endif
MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->out_iv,
ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
diff --git a/library/version_features.c b/library/version_features.c
index 196b93c..f9d99af 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -309,9 +309,6 @@
#if defined(MBEDTLS_SHA256_SMALLER)
"MBEDTLS_SHA256_SMALLER",
#endif /* MBEDTLS_SHA256_SMALLER */
-#if defined(MBEDTLS_SSL_AEAD_RANDOM_IV)
- "MBEDTLS_SSL_AEAD_RANDOM_IV",
-#endif /* MBEDTLS_SSL_AEAD_RANDOM_IV */
#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
"MBEDTLS_SSL_ALL_ALERT_MESSAGES",
#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index 9041d44..d1d9a22 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -413,6 +413,9 @@
MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
sig_oid, sig_oid_len, sig, sig_len ) );
+ if( len > (size_t)( c2 - buf ) )
+ return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
c2 -= len;
memcpy( c2, c, len );
diff --git a/library/x509write_csr.c b/library/x509write_csr.c
index 0b9a285..8fd856b 100644
--- a/library/x509write_csr.c
+++ b/library/x509write_csr.c
@@ -213,6 +213,9 @@
MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
sig_oid, sig_oid_len, sig, sig_len ) );
+ if( len > (size_t)( c2 - buf ) )
+ return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
c2 -= len;
memcpy( c2, c, len );
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index d184d85..e73d011 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -286,8 +286,10 @@
# Usage: run_test name [-p proxy_cmd] srv_cmd cli_cmd cli_exit [option [...]]
# Options: -s pattern pattern that must be present in server output
# -c pattern pattern that must be present in client output
+# -u pattern lines after pattern must be unique in client output
# -S pattern pattern that must be absent in server output
# -C pattern pattern that must be absent in client output
+# -U pattern lines after pattern must be unique in server output
run_test() {
NAME="$1"
shift 1
@@ -419,29 +421,50 @@
do
case $1 in
"-s")
- if grep -v '^==' $SRV_OUT | grep "$2" >/dev/null; then :; else
- fail "-s $2"
+ if grep -v '^==' $SRV_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then :; else
+ fail "pattern '$2' MUST be present in the Server output"
return
fi
;;
"-c")
- if grep -v '^==' $CLI_OUT | grep "$2" >/dev/null; then :; else
- fail "-c $2"
+ if grep -v '^==' $CLI_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then :; else
+ fail "pattern '$2' MUST be present in the Client output"
return
fi
;;
"-S")
- if grep -v '^==' $SRV_OUT | grep "$2" >/dev/null; then
- fail "-S $2"
+ if grep -v '^==' $SRV_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then
+ fail "pattern '$2' MUST NOT be present in the Server output"
return
fi
;;
"-C")
- if grep -v '^==' $CLI_OUT | grep "$2" >/dev/null; then
- fail "-C $2"
+ if grep -v '^==' $CLI_OUT | grep -v 'Serious error when reading debug info' | grep "$2" >/dev/null; then
+ fail "pattern '$2' MUST NOT be present in the Client output"
+ return
+ fi
+ ;;
+
+ # The filtering in the following two options (-u and -U) do the following
+ # - ignore valgrind output
+ # - filter out everything but lines right after the pattern occurances
+ # - keep one of each non-unique line
+ # - count how many lines remain
+ # A line with '--' will remain in the result from previous outputs, so the number of lines in the result will be 1
+ # if there were no duplicates.
+ "-U")
+ if [ $(grep -v '^==' $SRV_OUT | grep -v 'Serious error when reading debug info' | grep -A1 "$2" | grep -v "$2" | sort | uniq -d | wc -l) -gt 1 ]; then
+ fail "lines following pattern '$2' must be unique in Server output"
+ return
+ fi
+ ;;
+
+ "-u")
+ if [ $(grep -v '^==' $CLI_OUT | grep -v 'Serious error when reading debug info' | grep -A1 "$2" | grep -v "$2" | sort | uniq -d | wc -l) -gt 1 ]; then
+ fail "lines following pattern '$2' must be unique in Client output"
return
fi
;;
@@ -572,6 +595,14 @@
-s "Protocol is DTLSv1.2" \
-s "Ciphersuite is TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384"
+# Test for uniqueness of IVs in AEAD ciphersuites
+run_test "Unique IV in GCM" \
+ "$P_SRV exchanges=20 debug_level=4" \
+ "$P_CLI exchanges=20 debug_level=4 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384" \
+ 0 \
+ -u "IV used" \
+ -U "IV used"
+
# Tests for rc4 option
requires_config_enabled MBEDTLS_REMOVE_ARC4_CIPHERSUITES
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index c3773ba..5120837 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -52,6 +52,10 @@
TEST_ASSERT( olen >= pem_len - 1 );
TEST_ASSERT( memcmp( buf, check_buf, pem_len - 1 ) == 0 );
+ ret = mbedtls_x509write_csr_der( &req, buf, pem_len / 2,
+ rnd_pseudo_rand, &rnd_info );
+ TEST_ASSERT( ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
exit:
mbedtls_x509write_csr_free( &req );
mbedtls_pk_free( &key );
@@ -125,6 +129,10 @@
TEST_ASSERT( olen >= pem_len - 1 );
TEST_ASSERT( memcmp( buf, check_buf, pem_len - 1 ) == 0 );
+ ret = mbedtls_x509write_crt_der( &crt, buf, pem_len / 2,
+ rnd_pseudo_rand, &rnd_info );
+ TEST_ASSERT( ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
exit:
mbedtls_x509write_crt_free( &crt );
mbedtls_pk_free( &issuer_key );