Update mbedTLS 38/222438/1
authorOleksii Beketov <ol.beketov@samsung.com>
Mon, 18 Nov 2019 11:31:52 +0000 (13:31 +0200)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Wed, 15 Jan 2020 03:20:49 +0000 (12:20 +0900)
https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/609
(cherry-picked from e75e05c54bbba696c56df79d72f5de3ca82d20a9)

Change-Id: Iee97e14f68f1e532886e4cb9bb265e0760b2c226
Signed-off-by: Oleksii Beketov <ol.beketov@samsung.com>
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
extlibs/mbedtls/SConscript
extlibs/mbedtls/ocf.patch
extlibs/mbedtls/prep.sh

index 152c4ba..53f618d 100644 (file)
@@ -32,7 +32,7 @@ start_dir = os.getcwd()
 # Right now this script assumes the revision is a tag, and not a branch or an arbitrary
 # commit. If this changes, update the check below, or else the script will always conclude
 # the repo is not up to date because a tag with that name doesn't exist.
-mbedtls_revision = 'mbedtls-2.4.0'
+mbedtls_revision = 'mbedtls-2.16.2'
 
 if not os.path.exists(mbedtls_dir):
     print '''
@@ -143,6 +143,7 @@ mbedcrypto_src = [
                     'mbedtls/library/platform.c',
                     'mbedtls/library/ripemd160.c',
                     'mbedtls/library/rsa.c',
+                    'mbedtls/library/rsa_internal.c',
                     'mbedtls/library/sha1.c',
                     'mbedtls/library/sha256.c',
                     'mbedtls/library/sha512.c',
@@ -150,7 +151,11 @@ mbedcrypto_src = [
                     'mbedtls/library/timing.c',
                     'mbedtls/library/version.c',
                     'mbedtls/library/version_features.c',
-                    'mbedtls/library/xtea.c'
+                    'mbedtls/library/xtea.c',
+                    'mbedtls/library/platform_util.c',
+                    'mbedtls/library/chachapoly.c',
+                    'mbedtls/library/poly1305.c',
+                    'mbedtls/library/chacha20.c'
         ]
 
 mbeX509_src = [
index 139787a..8360e5c 100644 (file)
@@ -1,8 +1,8 @@
 diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
-index a95af6c..a3852b2 100644
+index b86e580..ed904fe 100644
 --- a/include/mbedtls/check_config.h
 +++ b/include/mbedtls/check_config.h
-@@ -184,6 +184,11 @@
+@@ -250,6 +250,11 @@
  #error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
  #endif
  
@@ -15,10 +15,10 @@ index a95af6c..a3852b2 100644
      ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) ||          \
        !defined(MBEDTLS_X509_CRT_PARSE_C) )
 diff --git a/include/mbedtls/compat-1.3.h b/include/mbedtls/compat-1.3.h
-index 27abbd9..fa4db26 100644
+index a58b472..2b2203e 100644
 --- a/include/mbedtls/compat-1.3.h
 +++ b/include/mbedtls/compat-1.3.h
-@@ -264,6 +264,9 @@
+@@ -268,6 +268,9 @@
  #if defined MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
  #define POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
  #endif
@@ -28,7 +28,7 @@ index 27abbd9..fa4db26 100644
  #if defined MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
  #define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
  #endif
-@@ -1273,6 +1276,7 @@
+@@ -1244,6 +1247,7 @@
  #define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
  #define POLARSSL_KEY_EXCHANGE_ECDHE_PSK MBEDTLS_KEY_EXCHANGE_ECDHE_PSK
  #define POLARSSL_KEY_EXCHANGE_ECDHE_RSA MBEDTLS_KEY_EXCHANGE_ECDHE_RSA
@@ -36,7 +36,7 @@ index 27abbd9..fa4db26 100644
  #define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA
  #define POLARSSL_KEY_EXCHANGE_ECDH_RSA MBEDTLS_KEY_EXCHANGE_ECDH_RSA
  #define POLARSSL_KEY_EXCHANGE_NONE MBEDTLS_KEY_EXCHANGE_NONE
-@@ -1616,6 +1620,7 @@
+@@ -1586,6 +1590,7 @@
  #define TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
  #define TLS_ECDHE_RSA_WITH_NULL_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA
  #define TLS_ECDHE_RSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
@@ -45,10 +45,10 @@ index 27abbd9..fa4db26 100644
  #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
  #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
 diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
-index 3b7c85b..5bef190 100644
+index 654f972..f6ef4ec 100644
 --- a/include/mbedtls/config.h
 +++ b/include/mbedtls/config.h
-@@ -642,6 +642,21 @@
+@@ -962,6 +962,21 @@
  #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
  
  /**
@@ -70,7 +70,7 @@ index 3b7c85b..5bef190 100644
   * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
   *
   * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS.
-@@ -1239,7 +1254,7 @@
+@@ -1566,7 +1581,7 @@
   *
   * Comment this macro to disable support for SSL session tickets
   */
@@ -79,7 +79,7 @@ index 3b7c85b..5bef190 100644
  
  /**
   * \def MBEDTLS_SSL_EXPORT_KEYS
-@@ -1479,6 +1494,7 @@
+@@ -1833,6 +1848,7 @@
   *      MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
   *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
   *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
@@ -88,10 +88,10 @@ index 3b7c85b..5bef190 100644
   * PEM_PARSE uses AES for decrypting encrypted keys.
   */
 diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
-index 82c0760..88103ad 100644
+index d31f6cd..fae852e 100644
 --- a/include/mbedtls/ssl.h
 +++ b/include/mbedtls/ssl.h
-@@ -356,7 +356,8 @@ union mbedtls_ssl_premaster_secret
+@@ -391,7 +391,8 @@ union mbedtls_ssl_premaster_secret
  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)    || \
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)  || \
      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)     || \
@@ -102,10 +102,10 @@ index 82c0760..88103ad 100644
  #endif
  #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
 diff --git a/include/mbedtls/ssl_ciphersuites.h b/include/mbedtls/ssl_ciphersuites.h
-index deaaa37..4f10540 100644
+index 71053e5..311fb62 100644
 --- a/include/mbedtls/ssl_ciphersuites.h
 +++ b/include/mbedtls/ssl_ciphersuites.h
-@@ -158,6 +158,8 @@ extern "C" {
+@@ -165,6 +165,8 @@ extern "C" {
  #define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256     0xC031 /**< TLS 1.2 */
  #define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384     0xC032 /**< TLS 1.2 */
  
@@ -114,7 +114,7 @@ index deaaa37..4f10540 100644
  #define MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA           0xC033 /**< Not in SSL3! */
  #define MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA      0xC034 /**< Not in SSL3! */
  #define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA       0xC035 /**< Not in SSL3! */
-@@ -247,6 +249,7 @@ typedef enum {
+@@ -302,6 +304,7 @@ typedef enum {
      MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
      MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
      MBEDTLS_KEY_EXCHANGE_ECJPAKE,
@@ -122,8 +122,8 @@ index deaaa37..4f10540 100644
  } mbedtls_key_exchange_type_t;
  
  /* Key exchanges using a certificate */
-@@ -271,7 +274,8 @@ typedef enum {
- /* Key exchanges using ECDHE */
+@@ -373,7 +376,8 @@ typedef enum {
+ /* Key exchanges using ECDHE */
  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)     || \
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)   || \
 -    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
@@ -132,52 +132,11 @@ index deaaa37..4f10540 100644
  #define MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED
  #endif
  
-diff --git a/library/entropy_poll.c b/library/entropy_poll.c
-index a116e60..c022caf 100644
---- a/library/entropy_poll.c
-+++ b/library/entropy_poll.c
-@@ -54,28 +54,29 @@
- #define _WIN32_WINNT 0x0400
- #endif
- #include <windows.h>
--#include <wincrypt.h>
-+#include <bcrypt.h>
- int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len,
-                            size_t *olen )
- {
--    HCRYPTPROV provider;
-     ((void) data);
-     *olen = 0;
--    if( CryptAcquireContext( &provider, NULL, NULL,
--                              PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
-+    /*
-+     * size_t may be 64 bits, but ULONG is always 32.
-+     * If len is larger than the maximum for ULONG, just fail.
-+     * It's unlikely anything ever will want to ask for this much randomness.
-+     */
-+    if ( len > 0xFFFFFFFFULL )
-     {
-         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
-     }
--    if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
-+    if ( !BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, (ULONG) len, BCRYPT_USE_SYSTEM_PREFERRED_RNG)) )
-     {
--        CryptReleaseContext( provider, 0 );
-         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
-     }
--    CryptReleaseContext( provider, 0 );
-     *olen = len;
-     return( 0 );
 diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
-index 3546331..74cef29 100644
+index 518f7dd..3d97b55 100644
 --- a/library/ssl_ciphersuites.c
 +++ b/library/ssl_ciphersuites.c
-@@ -96,6 +96,7 @@ static const int ciphersuite_preference[] =
+@@ -108,6 +108,7 @@ static const int ciphersuite_preference[] =
      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8,
@@ -185,7 +144,7 @@ index 3546331..74cef29 100644
  
      /* All CAMELLIA-128 ephemeral suites */
      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
-@@ -408,6 +409,22 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
+@@ -526,6 +527,22 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
  #endif /* MBEDTLS_CIPHER_NULL_CIPHER */
  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
  
@@ -208,19 +167,19 @@ index 3546331..74cef29 100644
  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
  #if defined(MBEDTLS_AES_C)
  #if defined(MBEDTLS_SHA1_C)
-@@ -1830,6 +1847,7 @@ int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
-         case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
+@@ -2345,6 +2362,7 @@ int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
          case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
          case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+         case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
 +        case MBEDTLS_KEY_EXCHANGE_ECDH_ANON:
              return( 1 );
  
          default:
 diff --git a/library/ssl_cli.c b/library/ssl_cli.c
-index cd39db0..1347167 100644
+index afced7a..9a49586 100644
 --- a/library/ssl_cli.c
 +++ b/library/ssl_cli.c
-@@ -1897,7 +1897,8 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char *
+@@ -2023,7 +2023,8 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char *
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
@@ -230,7 +189,7 @@ index cd39db0..1347167 100644
  static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
  {
      const mbedtls_ecp_curve_info *curve_info;
-@@ -1927,11 +1928,13 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
+@@ -2060,11 +2061,13 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
            MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
@@ -246,7 +205,7 @@ index cd39db0..1347167 100644
  static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
                                           unsigned char **p,
                                           unsigned char *end )
-@@ -1963,40 +1966,75 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
+@@ -2100,47 +2103,80 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
  }
  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
@@ -262,7 +221,7 @@ index cd39db0..1347167 100644
 -    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
 -    size_t  len;
 -    ((void) ssl);
-+        int ret = 0;
++    int ret = 0;
 +    size_t n;
 +
 +    if( ssl->conf->f_psk == NULL &&
@@ -279,23 +238,27 @@ index cd39db0..1347167 100644
 -     * opaque psk_identity_hint<0..2^16-1>;
 +     * Receive client pre-shared key identity name
       */
--    len = (*p)[0] << 8 | (*p)[1];
+-    if( end - (*p) < 2 )
 +    if( *p + 2 > end )
-+    {
+     {
+-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message "
+-                                    "(psk_identity_hint length)" ) );
+-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
 +        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
 +        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
-+    }
+     }
+-    len = (*p)[0] << 8 | (*p)[1];
 +
 +    n = ( (*p)[0] << 8 ) | (*p)[1];
      *p += 2;
  
--    if( (*p) + len > end )
-+    if( n < 1 || n > 65535 || *p + n > end )
+-    if( end - (*p) < (int) len )
++    if (n == 0)
      {
--        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) );
+-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message "
+-                                    "(psk_identity_hint length)" ) );
 -        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
-+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
++        return ( 0 );
      }
  
 -    /*
@@ -305,6 +268,13 @@ index cd39db0..1347167 100644
 -     */
 -    *p += len;
 -    ret = 0;
++    if( n < 1 || n > 65535 || *p + n > end )
++    {
++        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
++        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
++    }
+
+-    return( ret );
 +    if( ssl->conf->f_psk != NULL )
 +    {
 +        if( ssl->conf->f_psk( ssl->conf->p_psk, ssl, *p, n ) != 0 )
@@ -320,8 +290,7 @@ index cd39db0..1347167 100644
 +            ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
 +        }
 +    }
--    return( ret );
++
 +    if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY )
 +    {
 +        MBEDTLS_SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n );
@@ -341,7 +310,7 @@ index cd39db0..1347167 100644
  }
  #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
  
-@@ -2292,10 +2330,12 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
+@@ -2465,10 +2501,12 @@ start_processing:
            MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
@@ -356,7 +325,7 @@ index cd39db0..1347167 100644
      {
          if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
          {
-@@ -2306,7 +2346,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
+@@ -2481,7 +2519,8 @@ start_processing:
      else
  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
@@ -366,11 +335,11 @@ index cd39db0..1347167 100644
  #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
      {
-@@ -2377,6 +2418,13 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
+@@ -2555,6 +2594,13 @@ start_processing:
              return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
          }
  
-+// Anonim cipher suite without sign, ecdh param only
++// Anonymous cipher suite without sign, ecdh param only
 +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
 +        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
 +        {
@@ -380,27 +349,35 @@ index cd39db0..1347167 100644
          /*
           * Read signature
           */
-@@ -2525,7 +2573,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
-         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
-         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
-         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
--        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+@@ -2674,7 +2720,12 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
+
+     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
+
+-    if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
++    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
++        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
++        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
++        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
          ssl->state++;
-@@ -2550,7 +2599,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
-         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
-         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
-         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
--        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+@@ -2696,7 +2747,12 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
+
+     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
+
+-    if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
++    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
++        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
++        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
++        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
          ssl->state++;
-@@ -2753,11 +2803,13 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
+@@ -2939,11 +2995,13 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
@@ -416,7 +393,7 @@ index cd39db0..1347167 100644
      {
          /*
           * ECDH key exchange -- send client public value
-@@ -2792,7 +2844,8 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
+@@ -3009,7 +3067,8 @@ ecdh_calc_secret:
  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
@@ -424,9 +401,9 @@ index cd39db0..1347167 100644
 +          MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
 +          MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED */
  #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-     if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
-         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
-@@ -2980,7 +3033,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
+     if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) )
+     {
+@@ -3198,7 +3257,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
@@ -436,7 +413,7 @@ index cd39db0..1347167 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
          ssl->state++;
-@@ -3013,7 +3067,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
+@@ -3241,7 +3301,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
@@ -447,10 +424,10 @@ index cd39db0..1347167 100644
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
          ssl->state++;
 diff --git a/library/ssl_srv.c b/library/ssl_srv.c
-index 7271045..2964015 100644
+index bc77f80..5665cfd 100644
 --- a/library/ssl_srv.c
 +++ b/library/ssl_srv.c
-@@ -2500,6 +2500,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
+@@ -2696,6 +2696,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
@@ -458,45 +435,321 @@ index 7271045..2964015 100644
          authmode == MBEDTLS_SSL_VERIFY_NONE )
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
-@@ -2677,7 +2678,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
-     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
-     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
-     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
--    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) ||                        \
-+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
-     unsigned char *p = ssl->out_msg + 4;
-     unsigned char *dig_signed = p;
-     size_t dig_signed_len = 0, len;
-@@ -2738,12 +2740,11 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
+@@ -2953,8 +2954,10 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
      {
--        /* Note: we don't support identity hints, until someone asks
--         * for them. */
--        *(p++) = 0x00;
--        *(p++) = 0x00;
--
--        n += 2;
-+        *(p++) = (unsigned char)( ssl->conf->psk_identity_len >> 8 );
-+        *(p++) = (unsigned char)( ssl->conf->psk_identity_len      );
-+        memcpy(p, ssl->conf->psk_identity, ssl->conf->psk_identity_len);
-+        p += ssl->conf->psk_identity_len;
-+        n += ssl->conf->psk_identity_len + 2;
+-        ssl->out_msg[ssl->out_msglen++] = 0x00;
+-        ssl->out_msg[ssl->out_msglen++] = 0x00;
++        ssl->out_msg[ssl->out_msglen++] = (unsigned char)( ssl->conf->psk_identity_len >> 8 );
++        ssl->out_msg[ssl->out_msglen++] = (unsigned char)( ssl->conf->psk_identity_len      );
++        memcpy(ssl->out_msg+ssl->out_msglen, ssl->conf->psk_identity, ssl->conf->psk_identity_len);
++        ssl->out_msg[ssl->out_msglen] += ssl->conf->psk_identity_len;
      }
  #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
-@@ -2800,7 +2801,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
- #if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
-     if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
-         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
--        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
-+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
-+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON)
+@@ -3259,101 +3262,231 @@ curve_matching_done:
+  * that do not include a ServerKeyExchange message, do nothing. Either
+  * way, if successful, move on to the next step in the SSL state
+  * machine. */
++
+ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
+ {
+     int ret;
+-    size_t signature_len = 0;
+-#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
++    size_t n = 0;
+     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+                             ssl->transform_negotiate->ciphersuite_info;
+-#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
++
++    if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON ||
++        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK)
++    {
++#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
++    defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
++    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
++    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
++    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
++    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) ||                        \
++    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
++        unsigned char *p = ssl->out_msg + 4;
++        size_t len;
++#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */
+
+-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
++        MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
+
++        /* Key exchanges not involving ephemeral keys don't use
++         * ServerKeyExchange, so end here. */
+ #if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
+-    /* Extract static ECDH parameters and abort if ServerKeyExchange
+-     * is not needed. */
+-    if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) )
+-    {
+-        /* For suites involving ECDH, extract DH parameters
+-         * from certificate at this point. */
+-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
+-        if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
++        if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) )
+         {
+-            ssl_get_ecdh_params_from_cert( ssl );
++            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
++            ssl->state++;
++            return( 0 );
+         }
+-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
++#endif /* MBEDTLS_KEY_EXCHANGE__NON_PFS__ENABLED */
++
++        /*
++         *
++         * Part 2: Provide key exchange parameters for chosen ciphersuite.
++         *
++         */
++
++        /*
++         * For (EC)DHE key exchanges with PSK, parameters are prefixed by support
++         * identity hint (RFC 4279, Sec. 3). Until someone needs this feature,
++         * we use empty support identity hints here.
++         **/
++#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)   || \
++    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
++        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
++            ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
++        {
++            *(p++) = (unsigned char)( ssl->conf->psk_identity_len >> 8 );
++            *(p++) = (unsigned char)( ssl->conf->psk_identity_len      );
++            memcpy(p, ssl->conf->psk_identity, ssl->conf->psk_identity_len);
++            p += ssl->conf->psk_identity_len;
++            n += ssl->conf->psk_identity_len + 2;
++        }
++#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
++          MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
++
++        /*
++         * - ECDHE key exchanges
++         */
++#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
++        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
++            ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
++            ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
++            ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON)
++        {
++            /*
++             * Ephemeral ECDH parameters:
++             *
++             * struct {
++             *     ECParameters curve_params;
++             *     ECPoint      public;
++             * } ServerECDHParams;
++             */
++            const mbedtls_ecp_curve_info **curve = NULL;
++            const mbedtls_ecp_group_id *gid;
++
++            /* Match our preference list against the offered curves */
++            for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
++                for( curve = ssl->handshake->curves; *curve != NULL; curve++ )
++                    if( (*curve)->grp_id == *gid )
++                        goto curve_matching_done;
++
++curve_matching_done:
++            if( curve == NULL || *curve == NULL )
++            {
++                MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) );
++                return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
++            }
++
++            MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) );
++
++            if( ( ret = mbedtls_ecp_group_load( &ssl->handshake->ecdh_ctx.grp,
++                                           (*curve)->grp_id ) ) != 0 )
++            {
++                MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecp_group_load", ret );
++                return( ret );
++            }
++
++            if( ( ret = mbedtls_ecdh_make_params( &ssl->handshake->ecdh_ctx, &len,
++                                          p, /*ssl->out.max_content_len*/MBEDTLS_SSL_OUT_CONTENT_LEN - n,
++                                          ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
++            {
++                MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret );
++                return( ret );
++            }
++
++            p += len;
++            n += len;
++
++            MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q );
++        }
++#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */
++
++        /* Done with actual work; add header and send. */
++
++        ssl->out_msglen  = 4 + n;
++        ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
++        ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
+
+-        /* Key exchanges not involving ephemeral keys don't use
+-         * ServerKeyExchange, so end here. */
+-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
+         ssl->state++;
+-        return( 0 );
+-    }
+-#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
+
+-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
+-    defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+-    /* If we have already prepared the message and there is an ongoing
+-     * signature operation, resume signing. */
+-    if( ssl->handshake->async_in_progress != 0 )
+-    {
+-        MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming signature operation" ) );
+-        ret = ssl_resume_server_key_exchange( ssl, &signature_len );
++        if( ( ret = /*mbedtls_ssl_write_record*/mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
++        {
++            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
++            return( ret );
++        }
++        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) );
++
++        return( 0 );
+     }
+     else
+-#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
+-          defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
      {
-         /*
-          * Ephemeral ECDH parameters:
-@@ -3338,11 +3340,13 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
+-        /* ServerKeyExchange is needed. Prepare the message. */
+-        ret = ssl_prepare_server_key_exchange( ssl, &signature_len );
+-    }
++        size_t signature_len = 0;
+
+-    if( ret != 0 )
+-    {
+-        /* If we're starting to write a new message, set ssl->out_msglen
+-         * to 0. But if we're resuming after an asynchronous message,
+-         * out_msglen is the amount of data written so far and mst be
+-         * preserved. */
+-        if( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
+-            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange (pending)" ) );
++        MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
++
++#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
++        // Extract static ECDH parameters and abort if ServerKeyExchange
++        // is not needed.
++        if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) )
++        {
++            // For suites involving ECDH, extract DH parameters
++            // from certificate at this point.
++#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
++            if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
++            {
++                ssl_get_ecdh_params_from_cert( ssl );
++            }
++#endif // MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED
++
++            // Key exchanges not involving ephemeral keys don't use
++            // ServerKeyExchange, so end here.
++            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
++            ssl->state++;
++            return( 0 );
++        }
++#endif // MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED
++
++#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
++    defined(MBEDTLS_SSL_ASYNC_PRIVATE)
++        // If we have already prepared the message and there is an ongoing
++        // signature operation, resume signing.
++        if( ssl->handshake->async_in_progress != 0 )
++        {
++            MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming signature operation" ) );
++            ret = ssl_resume_server_key_exchange( ssl, &signature_len );
++        }
+         else
+-            ssl->out_msglen = 0;
+-        return( ret );
+-    }
++#endif // defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
++           // defined(MBEDTLS_SSL_ASYNC_PRIVATE)
++        {
++            // ServerKeyExchange is needed. Prepare the message.
++            ret = ssl_prepare_server_key_exchange( ssl, &signature_len );
++        }
++
++        if( ret != 0 )
++        {
++            // If we're starting to write a new message, set ssl->out_msglen
++            // to 0. But if we're resuming after an asynchronous message,
++            // out_msglen is the amount of data written so far and mst be
++            // preserved.
++            if( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
++                MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange (pending)" ) );
++            else
++                ssl->out_msglen = 0;
++            return( ret );
++        }
+
+-    /* If there is a signature, write its length.
+-     * ssl_prepare_server_key_exchange already wrote the signature
+-     * itself at its proper place in the output buffer. */
++        // If there is a signature, write its length.
++        // ssl_prepare_server_key_exchange already wrote the signature
++        // itself at its proper place in the output buffer.
+ #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+-    if( signature_len != 0 )
+-    {
+-        ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 );
+-        ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len      );
++        if( signature_len != 0 )
++        {
++            ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 );
++            ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len      );
+
+-        MBEDTLS_SSL_DEBUG_BUF( 3, "my signature",
+-                               ssl->out_msg + ssl->out_msglen,
+-                               signature_len );
++            MBEDTLS_SSL_DEBUG_BUF( 3, "my signature",
++                                   ssl->out_msg + ssl->out_msglen,
++                                   signature_len );
+
+-        /* Skip over the already-written signature */
+-        ssl->out_msglen += signature_len;
+-    }
+-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
++            // Skip over the already-written signature
++            ssl->out_msglen += signature_len;
++        }
++#endif // MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED
+
+-    /* Add header and send. */
+-    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+-    ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
++        // Add header and send.
++        ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
++        ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
+
+-    ssl->state++;
++        ssl->state++;
+
+-    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+-    {
+-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+-        return( ret );
+-    }
++        if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
++        {
++            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
++            return( ret );
++        }
+
+-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) );
+-    return( 0 );
++        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) );
++        return( 0 );
++    }
+ }
+
+ static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl )
+@@ -3782,11 +3915,13 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
@@ -512,17 +765,17 @@ index 7271045..2964015 100644
      {
          if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx,
                                        p, end - p) ) != 0 )
-@@ -3539,7 +3543,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
+@@ -4002,7 +4137,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
-+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
++        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON)
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
          ssl->state++;
-@@ -3570,6 +3575,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
+@@ -4034,6 +4170,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
@@ -531,10 +784,10 @@ index 7271045..2964015 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
 diff --git a/library/ssl_tls.c b/library/ssl_tls.c
-index 80a908d..94c8fd7 100644
+index 38690fa..88273a3 100644
 --- a/library/ssl_tls.c
 +++ b/library/ssl_tls.c
-@@ -4037,7 +4037,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
+@@ -5285,7 +5285,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
@@ -544,7 +797,7 @@ index 80a908d..94c8fd7 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
          ssl->state++;
-@@ -4057,7 +4058,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
+@@ -5305,7 +5306,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
@@ -554,7 +807,7 @@ index 80a908d..94c8fd7 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
          ssl->state++;
-@@ -4080,7 +4082,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
+@@ -5331,7 +5333,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
@@ -564,7 +817,7 @@ index 80a908d..94c8fd7 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
          ssl->state++;
-@@ -4196,7 +4199,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
+@@ -5657,7 +5660,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
@@ -574,7 +827,7 @@ index 80a908d..94c8fd7 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
          ssl->state++;
-@@ -7510,6 +7514,7 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
+@@ -9503,6 +9507,7 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
              case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
              case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
              case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
@@ -583,10 +836,10 @@ index 80a908d..94c8fd7 100644
          }
      }
 diff --git a/library/version_features.c b/library/version_features.c
-index 5d20ba0..6404a0c 100644
+index 24143d0..88335d3 100644
 --- a/library/version_features.c
 +++ b/library/version_features.c
-@@ -264,6 +264,9 @@ static const char *features[] = {
+@@ -372,6 +372,9 @@ static const char *features[] = {
  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
      "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED",
  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
@@ -596,48 +849,3 @@ index 5d20ba0..6404a0c 100644
  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
      "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED",
  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
-diff --git a/library/x509_crt.c b/library/x509_crt.c
-index af6c2a4..6dcb6aa 100644
---- a/library/x509_crt.c
-+++ b/library/x509_crt.c
-@@ -62,6 +62,7 @@
- #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
- #include <windows.h>
-+#include <intsafe.h>
- #else
- #include <time.h>
- #endif
-@@ -1108,6 +1109,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
-     char filename[MAX_PATH];
-     char *p;
-     size_t len = strlen( path );
-+    int lengthAsInt = 0;
-     WIN32_FIND_DATAW file_data;
-     HANDLE hFind;
-@@ -1122,7 +1124,10 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
-     p = filename + len;
-     filename[len++] = '*';
--    w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir,
-+    if ( FAILED ( SizeTToInt( len, &lengthAsInt ) ) )
-+        return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
-+
-+    w_ret = MultiByteToWideChar( CP_ACP, 0, filename, lengthAsInt, szDir,
-                                  MAX_PATH - 3 );
-     if( w_ret == 0 )
-         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
-@@ -1139,8 +1144,11 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
-         if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
-             continue;
-+        if ( FAILED( SizeTToInt( wcslen( file_data.cFileName ), &lengthAsInt ) ) )
-+            return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
-+
-         w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
--                                     lstrlenW( file_data.cFileName ),
-+                                     lengthAsInt,
-                                      p, (int) len - 1,
-                                      NULL, NULL );
-         if( w_ret == 0 )
index acc660a..b8b90f1 100755 (executable)
@@ -9,7 +9,7 @@ mbedtls_url="https://github.com/ARMmbed/mbedtls"
 mbedtls_dir=`dirname -- "$(readlink -f "$0")"`/mbedtls
 mbedtls_reldir="extlibs/mbedtls/mbedtls"
 
-mbedtls_revision="mbedtls-2.4.0"
+mbedtls_revision="mbedtls-2.16.2"
 if [ ! -d ${mbedtls_dir} ]; then
     echo ""
     echo "*********************************** Error: ****************************************"