Merge remote-tracking branch 'public/pr/1899' into mbedtls-2.7
diff --git a/ChangeLog b/ChangeLog
index 559f29c..5861841 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,42 @@
    * Fix failure in hmac_drbg in the benchmark sample application, when
      MBEDTLS_THREADING_C is defined. Found by TrinityTonic, #1095
 
+= mbed TLS 2.7.6 branch released 2018-08-31
+
+Security
+   * Fix an issue in the X.509 module which could lead to a buffer overread
+     during certificate extensions parsing. In case of receiving malformed
+     input (extensions length field equal to 0), an illegal read of one byte
+     beyond the input buffer is made. Found and analyzed by Nathan Crandall.
+
+Bugfix
+   * Fix a potential memory leak in mbedtls_ssl_setup() function. An allocation
+     failure in the function could lead to other buffers being leaked.
+   * Fixes a missing test dependency on MBEDTLS_ARC4_C. #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)
+   * Fix memory leak and free without initialization in pk_encrypt
+     and pk_decrypt example programs. Reported by Brace Stout. Fixes #1128.
+
+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/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index 465ef95..215db13 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -24,7 +24,7 @@
  */
 
 /**
- * @mainpage mbed TLS v2.7.5 source code documentation
+ * @mainpage mbed TLS v2.7.6 source code documentation
  *
  * This documentation describes the internal structure of mbed TLS.  It was
  * automatically generated from specially formatted comment blocks in
diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile
index bd52d24..f2f6603 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -28,7 +28,7 @@
 # identify the project. Note that if you do not use Doxywizard you need
 # to put quotes around the project name if it contains spaces.
 
-PROJECT_NAME           = "mbed TLS v2.7.5"
+PROJECT_NAME           = "mbed TLS v2.7.6"
 
 # The PROJECT_NUMBER tag can be used to enter a project or revision number.
 # This could be handy for archiving the generated documentation or
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index aa2764b..e84bd15 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -40,16 +40,16 @@
  */
 #define MBEDTLS_VERSION_MAJOR  2
 #define MBEDTLS_VERSION_MINOR  7
-#define MBEDTLS_VERSION_PATCH  5
+#define MBEDTLS_VERSION_PATCH  6
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02070500
-#define MBEDTLS_VERSION_STRING         "2.7.5"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.7.5"
+#define MBEDTLS_VERSION_NUMBER         0x02070600
+#define MBEDTLS_VERSION_STRING         "2.7.6"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.7.6"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 717b5f6..b408452 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -141,15 +141,15 @@
 
 if(USE_SHARED_MBEDTLS_LIBRARY)
     add_library(mbedcrypto SHARED ${src_crypto})
-    set_target_properties(mbedcrypto PROPERTIES VERSION 2.7.5 SOVERSION 2)
+    set_target_properties(mbedcrypto PROPERTIES VERSION 2.7.6 SOVERSION 2)
     target_link_libraries(mbedcrypto ${libs})
 
     add_library(mbedx509 SHARED ${src_x509})
-    set_target_properties(mbedx509 PROPERTIES VERSION 2.7.5 SOVERSION 0)
+    set_target_properties(mbedx509 PROPERTIES VERSION 2.7.6 SOVERSION 0)
     target_link_libraries(mbedx509 ${libs} mbedcrypto)
 
     add_library(mbedtls SHARED ${src_tls})
-    set_target_properties(mbedtls PROPERTIES VERSION 2.7.5 SOVERSION 10)
+    set_target_properties(mbedtls PROPERTIES VERSION 2.7.6 SOVERSION 10)
     target_link_libraries(mbedtls ${libs} mbedx509)
 
     install(TARGETS mbedtls mbedx509 mbedcrypto
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 7e068c7..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,
@@ -3315,8 +3327,8 @@
 
     msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
 
-    lifetime = ( msg[0] << 24 ) | ( msg[1] << 16 ) |
-               ( msg[2] <<  8 ) | ( msg[3]       );
+    lifetime = ( ((uint32_t) msg[0]) << 24 ) | ( msg[1] << 16 ) |
+               ( msg[2] << 8 ) | ( msg[3] );
 
     ticket_len = ( msg[4] << 8 ) | ( msg[5] );
 
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..da55801 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1582,6 +1582,8 @@
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
         if( auth_done == 0 )
         {
+            unsigned char mac[MBEDTLS_SSL_MAC_ADD];
+
             /*
              * MAC(MAC_write_key, seq_num +
              *     TLSCipherText.type +
@@ -1604,10 +1606,12 @@
             mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, pseudo_hdr, 13 );
             mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
                              ssl->out_iv, ssl->out_msglen );
-            mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc,
-                             ssl->out_iv + ssl->out_msglen );
+            mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac );
             mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
 
+            memcpy( ssl->out_iv + ssl->out_msglen, mac,
+                    ssl->transform_out->maclen );
+
             ssl->out_msglen += ssl->transform_out->maclen;
             auth_done++;
         }
@@ -5807,13 +5811,14 @@
     /*
      * Prepare base structures
      */
+    ssl->in_buf = NULL;
+    ssl->out_buf = NULL;
     if( ( ssl-> in_buf = mbedtls_calloc( 1, len ) ) == NULL ||
         ( ssl->out_buf = mbedtls_calloc( 1, len ) ) == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", len ) );
-        mbedtls_free( ssl->in_buf );
-        ssl->in_buf = NULL;
-        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+        goto error;
     }
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -5848,9 +5853,32 @@
     }
 
     if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
-        return( ret );
+        goto error;
 
     return( 0 );
+
+error:
+    mbedtls_free( ssl->in_buf );
+    mbedtls_free( ssl->out_buf );
+
+    ssl->conf = NULL;
+
+    ssl->in_buf = NULL;
+    ssl->out_buf = NULL;
+
+    ssl->in_hdr = NULL;
+    ssl->in_ctr = NULL;
+    ssl->in_len = NULL;
+    ssl->in_iv = NULL;
+    ssl->in_msg = NULL;
+
+    ssl->out_hdr = NULL;
+    ssl->out_ctr = NULL;
+    ssl->out_len = NULL;
+    ssl->out_iv = NULL;
+    ssl->out_msg = NULL;
+
+    return( ret );
 }
 
 /*
@@ -5911,7 +5939,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 +6716,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 +6737,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/library/x509_crt.c b/library/x509_crt.c
index 6751da0..b1af7ee 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -152,6 +152,9 @@
 static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile,
                                       mbedtls_md_type_t md_alg )
 {
+    if( md_alg == MBEDTLS_MD_NONE )
+        return( -1 );
+
     if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 )
         return( 0 );
 
@@ -165,6 +168,9 @@
 static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile,
                                       mbedtls_pk_type_t pk_alg )
 {
+    if( pk_alg == MBEDTLS_PK_NONE )
+        return( -1 );
+
     if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 )
         return( 0 );
 
@@ -196,6 +202,9 @@
     {
         mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id;
 
+        if( gid == MBEDTLS_ECP_DP_NONE )
+            return( -1 );
+
         if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 )
             return( 0 );
 
@@ -558,18 +567,14 @@
         end_ext_data = *p + len;
 
         /* Get extension ID */
-        extn_oid.tag = **p;
-
-        if( ( ret = mbedtls_asn1_get_tag( p, end, &extn_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
+        if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &extn_oid.len,
+                                          MBEDTLS_ASN1_OID ) ) != 0 )
             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
+        extn_oid.tag = MBEDTLS_ASN1_OID;
         extn_oid.p = *p;
         *p += extn_oid.len;
 
-        if( ( end - *p ) < 1 )
-            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
-                    MBEDTLS_ERR_ASN1_OUT_OF_DATA );
-
         /* Get optional critical */
         if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
             ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
diff --git a/programs/pkey/pk_decrypt.c b/programs/pkey/pk_decrypt.c
index 00bd71e..1d8c959 100644
--- a/programs/pkey/pk_decrypt.c
+++ b/programs/pkey/pk_decrypt.c
@@ -73,7 +73,10 @@
     const char *pers = "mbedtls_pk_decrypt";
     ((void) argv);
 
+    mbedtls_pk_init( &pk );
+    mbedtls_entropy_init( &entropy );
     mbedtls_ctr_drbg_init( &ctr_drbg );
+
     memset(result, 0, sizeof( result ) );
 
     if( argc != 2 )
@@ -90,20 +93,18 @@
     mbedtls_printf( "\n  . Seeding the random number generator..." );
     fflush( stdout );
 
-    mbedtls_entropy_init( &entropy );
-    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
-                               (const unsigned char *) pers,
-                               strlen( pers ) ) ) != 0 )
+    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
+                                       &entropy, (const unsigned char *) pers,
+                                       strlen( pers ) ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%04x\n",
+                        -ret );
         goto exit;
     }
 
     mbedtls_printf( "\n  . Reading private key from '%s'", argv[1] );
     fflush( stdout );
 
-    mbedtls_pk_init( &pk );
-
     if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_pk_parse_keyfile returned -0x%04x\n", -ret );
@@ -116,14 +117,16 @@
     if( ( f = fopen( "result-enc.txt", "rb" ) ) == NULL )
     {
         mbedtls_printf( "\n  ! Could not open %s\n\n", "result-enc.txt" );
+        ret = 1;
         goto exit;
     }
 
     i = 0;
-
     while( fscanf( f, "%02X", &c ) > 0 &&
            i < (int) sizeof( buf ) )
+    {
         buf[i++] = (unsigned char) c;
+    }
 
     fclose( f );
 
@@ -136,7 +139,8 @@
     if( ( ret = mbedtls_pk_decrypt( &pk, buf, i, result, &olen, sizeof(result),
                             mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_pk_decrypt returned -0x%04x\n", -ret );
+        mbedtls_printf( " failed\n  ! mbedtls_pk_decrypt returned -0x%04x\n",
+                        -ret );
         goto exit;
     }
 
@@ -147,13 +151,15 @@
     exit_code = MBEDTLS_EXIT_SUCCESS;
 
 exit:
-    mbedtls_ctr_drbg_free( &ctr_drbg );
+
+    mbedtls_pk_free( &pk );
     mbedtls_entropy_free( &entropy );
+    mbedtls_ctr_drbg_free( &ctr_drbg );
 
 #if defined(MBEDTLS_ERROR_C)
     if( exit_code != MBEDTLS_EXIT_SUCCESS )
     {
-        mbedtls_strerror( ret, (char *) buf, sizeof(buf) );
+        mbedtls_strerror( ret, (char *) buf, sizeof( buf ) );
         mbedtls_printf( "  !  Last error was: %s\n", buf );
     }
 #endif
diff --git a/programs/pkey/pk_encrypt.c b/programs/pkey/pk_encrypt.c
index 400619c..22dedba 100644
--- a/programs/pkey/pk_encrypt.c
+++ b/programs/pkey/pk_encrypt.c
@@ -73,6 +73,8 @@
     const char *pers = "mbedtls_pk_encrypt";
 
     mbedtls_ctr_drbg_init( &ctr_drbg );
+    mbedtls_entropy_init( &entropy );
+    mbedtls_pk_init( &pk );
 
     if( argc != 3 )
     {
@@ -88,20 +90,18 @@
     mbedtls_printf( "\n  . Seeding the random number generator..." );
     fflush( stdout );
 
-    mbedtls_entropy_init( &entropy );
-    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
-                               (const unsigned char *) pers,
-                               strlen( pers ) ) ) != 0 )
+    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
+                                       &entropy, (const unsigned char *) pers,
+                                       strlen( pers ) ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%04x\n", -ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%04x\n",
+                        -ret );
         goto exit;
     }
 
     mbedtls_printf( "\n  . Reading public key from '%s'", argv[1] );
     fflush( stdout );
 
-    mbedtls_pk_init( &pk );
-
     if( ( ret = mbedtls_pk_parse_public_keyfile( &pk, argv[1] ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_pk_parse_public_keyfile returned -0x%04x\n", -ret );
@@ -126,7 +126,8 @@
                             buf, &olen, sizeof(buf),
                             mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_pk_encrypt returned -0x%04x\n", -ret );
+        mbedtls_printf( " failed\n  ! mbedtls_pk_encrypt returned -0x%04x\n",
+                        -ret );
         goto exit;
     }
 
@@ -135,13 +136,17 @@
      */
     if( ( f = fopen( "result-enc.txt", "wb+" ) ) == NULL )
     {
-        mbedtls_printf( " failed\n  ! Could not create %s\n\n", "result-enc.txt" );
+        mbedtls_printf( " failed\n  ! Could not create %s\n\n",
+                        "result-enc.txt" );
+        ret = 1;
         goto exit;
     }
 
     for( i = 0; i < olen; i++ )
+    {
         mbedtls_fprintf( f, "%02X%s", buf[i],
                  ( i + 1 ) % 16 == 0 ? "\r\n" : " " );
+    }
 
     fclose( f );
 
@@ -150,13 +155,15 @@
     exit_code = MBEDTLS_EXIT_SUCCESS;
 
 exit:
-    mbedtls_ctr_drbg_free( &ctr_drbg );
+
+    mbedtls_pk_free( &pk );
     mbedtls_entropy_free( &entropy );
+    mbedtls_ctr_drbg_free( &ctr_drbg );
 
 #if defined(MBEDTLS_ERROR_C)
     if( exit_code != MBEDTLS_EXIT_SUCCESS )
     {
-        mbedtls_strerror( ret, (char *) buf, sizeof(buf) );
+        mbedtls_strerror( ret, (char *) buf, sizeof( buf ) );
         mbedtls_printf( "  !  Last error was: %s\n", buf );
     }
 #endif
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)
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index 85415d0..c55d628 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
 Check compiletime library version
-check_compiletime_version:"2.7.5"
+check_compiletime_version:"2.7.6"
 
 Check runtime library version
-check_runtime_version:"2.7.5"
+check_runtime_version:"2.7.6"
 
 Check for MBEDTLS_VERSION_C
 check_feature:"MBEDTLS_VERSION_C":0