Merge remote-tracking branch 'origin/pr/630' into baremetal
diff --git a/configs/baremetal.h b/configs/baremetal.h
index e4e3a2a..0bdee4f 100644
--- a/configs/baremetal.h
+++ b/configs/baremetal.h
@@ -46,7 +46,6 @@
 #define MBEDTLS_PK_C
 #define MBEDTLS_PK_PARSE_C
 #define MBEDTLS_PK_WRITE_C
-#define MBEDTLS_ECDH_C
 #define MBEDTLS_ECDSA_C
 #define MBEDTLS_ECP_C
 #define MBEDTLS_ECP_DP_SECP256R1_ENABLED
@@ -116,6 +115,8 @@
 #define MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET \
     MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED
 
+#define MBEDTLS_USE_TINYCRYPT
+
 /* X.509 CRT parsing */
 #define MBEDTLS_X509_USE_C
 #define MBEDTLS_X509_CRT_PARSE_C
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 29e61db..f28345d 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -103,6 +103,18 @@
 #error "MBEDTLS_USE_TINYCRYPT defined, but it cannot be defined with MBEDTLS_NO_64BIT_MULTIPLICATION"
 #endif
 
+#if defined(MBEDTLS_USE_TINYCRYPT) &&                                   \
+    !( defined(MBEDTLS_SSL_CONF_SINGLE_EC)     &&                       \
+       MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID == 23 &&                       \
+       MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID == MBEDTLS_ECP_DP_SECP256R1 )
+#error "MBEDTLS_USE_TINYCRYPT requires the use of MBEDTLS_SSL_CONF_SINGLE_EC to hardcode the choice of Secp256r1"
+#endif
+
+#if defined(MBEDTLS_USE_TINYCRYPT) && \
+    !defined(MBEDTLS_SSL_CONF_RNG)
+#error "MBEDTLS_USE_TINYCRYPT defined, but not all prerequesites"
+#endif
+
 #if defined(MBEDTLS_NIST_KW_C) && \
     ( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) )
 #error "MBEDTLS_NIST_KW_C defined, but not all prerequisites"
@@ -260,14 +272,17 @@
 #error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) &&                 \
-    ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) ||          \
-      !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) &&                  \
+    ( !( defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_USE_TINYCRYPT) ) || \
+      !defined(MBEDTLS_RSA_C)                                        || \
+      !defined(MBEDTLS_X509_CRT_PARSE_C)                             || \
+      !defined(MBEDTLS_PKCS1_V15) )
 #error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) &&                 \
-    ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) ||          \
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) &&                \
+    ( !( defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_USE_TINYCRYPT) ) || \
+      !defined(MBEDTLS_ECDSA_C) ||                                      \
       !defined(MBEDTLS_X509_CRT_PARSE_C) )
 #error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
 #endif
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 930f7c7..5da4f11 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -2536,6 +2536,15 @@
  * BSD, and can be found at https://github.com/intel/tinycrypt - this option
  * only enables the ECC modules from TinyCrypt.
  *
+ * Requires: MBEDTLS_SSL_CONF_RNG
+ *           MBEDTLS_SSL_CONF_SINGLE_EC
+ *           MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID == 23
+ *           MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID == MBEDTLS_ECP_DP_SECP256R1
+ *
+ * \see MBEDTLS_SSL_CONF_RNG
+ *
+ * \see MBEDTLS_SSL_CONF_SINGLE_EC
+ *
  * Module:  tinycrypt/ecc.c
  *          tinycrypt/ecc_dh.c
  *          tinycrypt/ecc_dsa.c
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index ce7c9a5..f8f4090 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -53,6 +53,11 @@
 #include "ecjpake.h"
 #endif
 
+#if defined(MBEDTLS_USE_TINYCRYPT)
+#include "tinycrypt/ecc.h"
+#include "tinycrypt/ecc_dh.h"
+#endif
+
 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
     !defined(inline) && !defined(__cplusplus)
 #define inline __inline
@@ -381,7 +386,9 @@
     size_t ecjpake_cache_len;                   /*!< Length of cached data */
 #endif
 #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+#if defined(MBEDTLS_ECDH_C)   ||                        \
+    defined(MBEDTLS_ECDSA_C)  ||                        \
+    defined(MBEDTLS_USE_TINYCRYPT) ||                   \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
     uint16_t curve_tls_id;                      /*!< TLS ID of EC for ECDHE. */
 #endif
@@ -542,6 +549,11 @@
      * The library does not use it internally. */
     void *user_async_ctx;
 #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+#if defined(MBEDTLS_USE_TINYCRYPT)
+    uint8_t ecdh_privkey[NUM_ECC_BYTES];
+    uint8_t ecdh_peerkey[2*NUM_ECC_BYTES];
+#endif /* MBEDTLS_USE_TINYCRYPT */
 };
 
 /*
@@ -1833,4 +1845,9 @@
 
 #define MBEDTLS_SSL_CHK(f) do { if( ( ret = f ) < 0 ) goto cleanup; } while( 0 )
 
+#if defined(MBEDTLS_USE_TINYCRYPT)
+int mbedtls_ssl_ecdh_read_peerkey( mbedtls_ssl_context *ssl,
+                                   unsigned char **p, unsigned char *end );
+#endif /* MBEDTLS_USE_TINYCRYPT */
+
 #endif /* ssl_internal.h */
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 050d8b5..8903431 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -250,7 +250,9 @@
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
           MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
 
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+#if defined(MBEDTLS_ECDH_C)   ||                           \
+    defined(MBEDTLS_ECDSA_C)  ||                           \
+    defined(MBEDTLS_USE_TINYCRYPT) ||                           \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
 static size_t ssl_get_ec_curve_list_length( mbedtls_ssl_context *ssl )
 {
@@ -332,7 +334,7 @@
 
     *olen = 6;
 }
-#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT ||
           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -1073,7 +1075,9 @@
     ext_len += olen;
 #endif
 
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+#if defined(MBEDTLS_ECDH_C)   ||                \
+    defined(MBEDTLS_ECDSA_C)  ||                \
+    defined(MBEDTLS_USE_TINYCRYPT) ||                \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
     if( uses_ec )
     {
@@ -1374,8 +1378,10 @@
 }
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
 
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
-    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+#if defined(MBEDTLS_ECDH_C)  ||                      \
+    defined(MBEDTLS_ECDSA_C) ||                      \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) || \
+    defined(MBEDTLS_USE_TINYCRYPT)
 static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
                                                   const unsigned char *buf,
                                                   size_t len )
@@ -1398,7 +1404,7 @@
         if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
             p[0] == MBEDTLS_ECP_PF_COMPRESSED )
         {
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_ECDH_C)
             ssl->handshake->ecdh_ctx.point_format = p[0];
 #endif
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -1417,7 +1423,7 @@
                                   MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
     return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
 }
-#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT ||
           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -2214,11 +2220,12 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
           MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
 
-#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+#if defined(MBEDTLS_ECDH_C) &&                                          \
+    ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)   ||              \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||              \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)   ||              \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)    ||              \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) )
 static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
 {
     const mbedtls_ecp_curve_info *curve_info;
@@ -2251,15 +2258,17 @@
 
     return( 0 );
 }
-#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
-          MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
-          MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
-          MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
-          MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+#endif /* MBEDTLS_ECDH_C &&
+         ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED   ||
+           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
+           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED   ||
+           MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED    ||
+           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED  ) */
 
-#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(MBEDTLS_ECDH_C) &&                                          \
+    ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)   ||              \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||              \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED))
 static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
                                          unsigned char **p,
                                          unsigned char *end )
@@ -2289,9 +2298,10 @@
 
     return( ret );
 }
-#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
-          MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
-          MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#endif /* MBEDTLS_ECDH_C &&
+          ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED   ||
+            MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
+            MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED    ) */
 
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
 static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
@@ -2796,9 +2806,42 @@
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
           MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#if defined(MBEDTLS_USE_TINYCRYPT)
+    if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
+        == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
+        mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
+        == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA )
+    {
+        static const unsigned char ecdh_group[] = {
+            MBEDTLS_ECP_TLS_NAMED_CURVE,
+            0  /* high bits of secp256r1 TLS ID  */,
+            23 /* low bits of secp256r1 TLS ID   */,
+        };
+
+        /* Check for fixed ECDH parameter preamble. */
+        if( (size_t)( end - p ) < sizeof( ecdh_group ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad server key exchange (too short)" ) );
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+
+        if( memcmp( p, ecdh_group, sizeof( ecdh_group ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad server key exchange (unexpected header)" ) );
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+        p += sizeof( ecdh_group );
+
+        /* Read server's key share. */
+        if( mbedtls_ssl_ecdh_read_peerkey( ssl, &p, end ) != 0 )
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+    }
+    else
+#endif /* MBEDTLS_USE_TINYCRYPT */
+#if defined(MBEDTLS_ECDH_C) &&                                          \
+    ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)   ||              \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)   ||              \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) )
     if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
         == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA                         ||
         mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
@@ -2815,9 +2858,10 @@
         }
     }
     else
-#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
-          MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
-          MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+#endif /* MBEDTLS_ECDH_C &&
+          ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+            MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
+            MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) */
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
     if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
         == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
@@ -3525,10 +3569,36 @@
     }
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+#if defined(MBEDTLS_USE_TINYCRYPT)
+    if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
+        == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
+        mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
+        == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA )
+    {
+        const struct uECC_Curve_t * uecc_curve = uECC_secp256r1();
+        ((void) n);
+        ((void) ret);
+
+        if( (size_t)( end - p ) < 2 * NUM_ECC_BYTES + 2 )
+            return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+        *p++ = 2 * NUM_ECC_BYTES + 1;
+        *p++ = 0x04; /* uncompressed point presentation */
+
+        if( !uECC_make_key( p, ssl->handshake->ecdh_privkey,
+                            uecc_curve ) )
+        {
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+        p += 2 * NUM_ECC_BYTES;
+    }
+    else
+#endif /* MBEDTLS_USE_TINYCRYPT */
+#if defined(MBEDTLS_ECDH_C) &&                                          \
+        ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)   ||          \
+          defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||          \
+          defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)    ||          \
+          defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) )
     if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
         == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
         mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
@@ -3566,10 +3636,11 @@
         p += n;
     }
     else
-#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
-          MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
-          MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
-          MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+#endif /* MBEDTLS_ECDH_C && (
+          ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED   ||
+            MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
+            MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED    ||
+            MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED  ) */
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
     if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) )
     {
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index b2b6144..c25482d 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -276,7 +276,9 @@
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
           MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
 
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+#if defined(MBEDTLS_ECDH_C)   ||                         \
+    defined(MBEDTLS_ECDSA_C)  ||                         \
+    defined(MBEDTLS_USE_TINYCRYPT) ||                         \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
 static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
                         const unsigned char *buf, size_t len,
@@ -348,7 +350,7 @@
         if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
             p[0] == MBEDTLS_ECP_PF_COMPRESSED )
         {
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_ECDH_C)
             ssl->handshake->ecdh_ctx.point_format = p[0];
 #endif
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -364,7 +366,7 @@
 
     return( 0 );
 }
-#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT
           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -972,7 +974,8 @@
     }
 #endif
 
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) ||      \
+    defined(MBEDTLS_USE_TINYCRYPT)
     if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) &&
         ssl->handshake->curve_tls_id == 0 )
     {
@@ -1922,8 +1925,10 @@
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
           MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
 
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
-    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+#if defined(MBEDTLS_ECDH_C)  ||                      \
+    defined(MBEDTLS_ECDSA_C) ||                      \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) || \
+    defined(MBEDTLS_USE_TINYCRYPT)
             case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) );
 
@@ -1944,7 +1949,8 @@
                     return( ret );
                 break;
 #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
-          MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+          MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED ||
+          MBEDTLS_USE_TINYCRYPT */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
             case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
@@ -2539,7 +2545,8 @@
 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
-    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) || \
+    defined(MBEDTLS_USE_TINYCRYPT)
 static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
                                                    unsigned char *buf,
                                                    size_t *olen )
@@ -2937,7 +2944,8 @@
 #endif
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
-    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) || \
+    defined(MBEDTLS_USE_TINYCRYPT)
     if ( mbedtls_ssl_ciphersuite_uses_ec(
            mbedtls_ssl_ciphersuite_from_id(
              mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ) ) ) )
@@ -3244,6 +3252,9 @@
     unsigned char *dig_signed = NULL;
 #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
 #endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */
+#if defined(MBEDTLS_USE_TINYCRYPT)
+    const struct uECC_Curve_t * uecc_curve = uECC_secp256r1();
+#endif
 
     (void) ciphersuite_info; /* unused in some configurations */
 #if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
@@ -3291,8 +3302,10 @@
      **/
 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)   || \
     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
-    if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
-        mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
+    if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) ==
+        MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
+        mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) ==
+        MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
     {
         ssl->out_msg[ssl->out_msglen++] = 0x00;
         ssl->out_msg[ssl->out_msglen++] = 0x00;
@@ -3370,44 +3383,88 @@
          *     ECPoint      public;
          * } ServerECDHParams;
          */
-        const mbedtls_ecp_curve_info *curve =
-            mbedtls_ecp_curve_info_from_tls_id( ssl->handshake->curve_tls_id );
-        int ret;
-        size_t len = 0;
 
-        if( curve == NULL )
+#if defined(MBEDTLS_USE_TINYCRYPT)
+        if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
+            == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
+            mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
+            == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA )
         {
-            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_ecdh_setup( &ssl->handshake->ecdh_ctx,
-                                        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,
-                  ssl->out_msg + ssl->out_msglen,
-                  MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen,
-                  mbedtls_ssl_conf_get_frng( ssl->conf ),
-                  mbedtls_ssl_conf_get_prng( ssl->conf ) ) ) != 0 )
-        {
-            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret );
-            return( ret );
-        }
+            static const unsigned char ecdh_param_hdr[] = {
+                MBEDTLS_ECP_TLS_NAMED_CURVE,
+                0  /* high bits of secp256r1 TLS ID  */,
+                23 /* low bits of secp256r1 TLS ID   */,
+                2 * NUM_ECC_BYTES + 1,
+                0x04 /* Uncompressed */
+            };
 
 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
-        dig_signed = ssl->out_msg + ssl->out_msglen;
+            dig_signed = ssl->out_msg + ssl->out_msglen;
 #endif
 
-        ssl->out_msglen += len;
+            memcpy( ssl->out_msg + ssl->out_msglen,
+                    ecdh_param_hdr, sizeof( ecdh_param_hdr ) );
+            ssl->out_msglen += sizeof( ecdh_param_hdr );
 
-        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
-                                MBEDTLS_DEBUG_ECDH_Q );
+            if( !uECC_make_key( &ssl->out_msg[ ssl->out_msglen ],
+                                ssl->handshake->ecdh_privkey,
+                                uecc_curve ) )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "Key creation failed" ) );
+                return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+            }
+
+            ssl->out_msglen += 2*NUM_ECC_BYTES;
+        }
+        else
+#endif /* MBEDTLS_ECDH_C */
+#if !defined(MBEDTLS_ECDH_C)
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+#else
+        {
+            const mbedtls_ecp_curve_info *curve =
+                mbedtls_ecp_curve_info_from_tls_id( ssl->handshake->curve_tls_id );
+            int ret;
+            size_t len = 0;
+
+            if( 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_ecdh_setup( &ssl->handshake->ecdh_ctx,
+                                            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,
+                      ssl->out_msg + ssl->out_msglen,
+                      MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen,
+                      mbedtls_ssl_conf_get_frng( ssl->conf ),
+                      mbedtls_ssl_conf_get_prng( ssl->conf ) ) ) != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret );
+                return( ret );
+            }
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+            dig_signed = ssl->out_msg + ssl->out_msglen;
+#endif
+
+            ssl->out_msglen += len;
+
+            MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                    MBEDTLS_DEBUG_ECDH_Q );
+        }
+#endif /* MBEDTLS_ECDH_C */
     }
 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */
 
@@ -4141,10 +4198,23 @@
     }
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+#if defined(MBEDTLS_USE_TINYCRYPT)
+    if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
+        == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA                    ||
+        mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
+        == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA )
+    {
+        ((void) ret);
+        if( mbedtls_ssl_ecdh_read_peerkey( ssl, &p, end ) != 0 )
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+    }
+    else
+#endif
+#if defined(MBEDTLS_ECDH_C) &&                                            \
+    ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)   ||                \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)    ||                \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) )
     if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
         == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
         mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 509fc8c..a6492f4 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -55,6 +55,47 @@
 #include "mbedtls/oid.h"
 #endif
 
+#if defined(MBEDTLS_USE_TINYCRYPT)
+static int uecc_rng_wrapper( uint8_t *dest, unsigned int size )
+{
+    int ret;
+    ret = mbedtls_ssl_conf_rng_func( NULL, dest, size );
+    if( ret == 0 )
+        return( (int) size );
+
+    return( 0 );
+}
+
+int mbedtls_ssl_ecdh_read_peerkey( mbedtls_ssl_context *ssl,
+                                   unsigned char **p, unsigned char *end )
+{
+    size_t const secp256r1_uncompressed_point_length =
+        1 /* length */ + 1 /* length */ + 2 * NUM_ECC_BYTES /* data */;
+
+    if( (size_t)( end - *p ) < secp256r1_uncompressed_point_length )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Bad ECDH peer pubkey (too short)" ) );
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+
+    if( (*p)[0] != 2 * NUM_ECC_BYTES + 1 ||
+        (*p)[1] != 0x04 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Unexpected ECDH peer pubkey header - expected { %#02x, %#02x }, got { %#02x, %#02x }",
+                               2 * NUM_ECC_BYTES + 1,
+                               0x04,
+                               (unsigned) (*p)[0],
+                               (unsigned) (*p)[1] ) );
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+
+    memcpy( ssl->handshake->ecdh_peerkey, *p + 2, 2 * NUM_ECC_BYTES );
+
+    *p += secp256r1_uncompressed_point_length;
+    return( 0 );
+}
+#endif /* MBEDTLS_USE_TINYCRYPT */
+
 static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl );
 static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl );
 
@@ -1660,6 +1701,27 @@
     mbedtls_ssl_ciphersuite_handle_t ciphersuite_info =
         mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake );
 
+#if defined(MBEDTLS_USE_TINYCRYPT)
+    if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
+        == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
+        mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
+        == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA )
+    {
+        const struct uECC_Curve_t * uecc_curve = uECC_secp256r1();
+        ((void) ret);
+
+        if( !uECC_shared_secret( ssl->handshake->ecdh_peerkey,
+                                 ssl->handshake->ecdh_privkey,
+                                 ssl->handshake->premaster,
+                                 uecc_curve ) )
+        {
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+
+        ssl->handshake->pmslen = NUM_ECC_BYTES;
+    }
+    else
+#endif
 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
     if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
         == MBEDTLS_KEY_EXCHANGE_DHE_RSA )
@@ -1679,10 +1741,11 @@
     }
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
-    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+#if defined(MBEDTLS_ECDH_C) &&                                          \
+    ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)   ||              \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||              \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)    ||              \
+      defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) )
     if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
         == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA                       ||
         mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
@@ -8234,6 +8297,10 @@
 
     ssl->conf = conf;
 
+#if defined(MBEDTLS_USE_TINYCRYPT)
+    uECC_set_rng( &uecc_rng_wrapper );
+#endif
+
     /*
      * Prepare base structures
      */
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 2415cdd..fe46b28 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1266,19 +1266,6 @@
     make test
 }
 
-component_build_tinycrypt_cmake () {
-    msg "build: tinycrypt native, cmake"
-    scripts/config.pl set MBEDTLS_USE_TINYCRYPT
-    CC=gcc cmake .
-    make
-}
-
-component_build_tinycrypt_make () {
-    msg "build: tinycrypt native, make"
-    scripts/config.pl set MBEDTLS_USE_TINYCRYPT
-    make CC=gcc CFLAGS='-Werror -O1'
-}
-
 component_test_no_x509_info () {
     msg "build: full + MBEDTLS_X509_REMOVE_INFO" # ~ 10s
     scripts/config.pl full
@@ -1355,15 +1342,6 @@
     if_build_succeeded tests/ssl-opt.sh --filter "^Default, DTLS$"
 }
 
-component_build_armcc_tinycrypt_baremetal () {
-    msg "build: ARM Compiler 5, make with tinycrypt and baremetal"
-    scripts/config.pl baremetal
-    scripts/config.pl set MBEDTLS_USE_TINYCRYPT
-
-    make CC="$ARMC5_CC" AR="$ARMC5_AR" WARNING_CFLAGS='--strict --c99' lib
-    make clean
-}
-
 component_test_allow_sha1 () {
     msg "build: allow SHA1 in certificates by default"
     scripts/config.pl set MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
diff --git a/tinycrypt/ecc.c b/tinycrypt/ecc.c
index 2e694cc..ab1956a 100644
--- a/tinycrypt/ecc.c
+++ b/tinycrypt/ecc.c
@@ -52,6 +52,12 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #if defined(MBEDTLS_USE_TINYCRYPT)
 #include <tinycrypt/ecc.h>
 #include <string.h>
diff --git a/tinycrypt/ecc_dh.c b/tinycrypt/ecc_dh.c
index 28dfdf9..8aae1a2 100644
--- a/tinycrypt/ecc_dh.c
+++ b/tinycrypt/ecc_dh.c
@@ -54,6 +54,13 @@
  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  *  POSSIBILITY OF SUCH DAMAGE.
  */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #if defined(MBEDTLS_USE_TINYCRYPT)
 #include <tinycrypt/ecc.h>
 #include <tinycrypt/ecc_dh.h>
diff --git a/tinycrypt/ecc_dsa.c b/tinycrypt/ecc_dsa.c
index 048fa61..3743091 100644
--- a/tinycrypt/ecc_dsa.c
+++ b/tinycrypt/ecc_dsa.c
@@ -53,6 +53,12 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
 #if defined(MBEDTLS_USE_TINYCRYPT)
 #include <tinycrypt/ecc.h>
 #include <tinycrypt/ecc_dsa.h>