tinyCrypt: Initial commit towards ECDHE support

This commit is a first step towards using uECC for ECDH
during TLS handshakes.
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index c729194..582c9fd 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 )
@@ -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)
@@ -3521,10 +3527,42 @@
     }
     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)
+    {
+        const struct uECC_Curve_t * uecc_curve = uECC_secp256r1();
+
+        uECC_set_rng( &mbetls_uecc_rng_wrapper );
+
+        if( !uECC_make_key( ssl->handshake->ecdh_ownpubkey,
+                            ssl->handshake->ecdh_privkey,
+                            uecc_curve ) )
+        {
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+
+        if( !uECC_shared_secret( ssl->handshake->ecdh_peerkey,
+                                 ssl->handshake->ecdh_privkey,
+                                 ssl->handshake->premaster,
+                                 uecc_curve ) )
+        {
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+
+        /* TODO: Write the client share. */
+        ((void) p);
+        ((void) end);
+        ((void) ret);
+        ((void) n);
+
+        mbedtls_platform_zeroize( ssl->handshake->ecdh_privkey, NUM_ECC_BYTES );
+    }
+    else
+#elif 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_srv.c b/library/ssl_srv.c
index 8ffbf7c..8f75f6a 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,
@@ -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 )
@@ -2936,7 +2943,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 ) ) ) )
@@ -3243,6 +3251,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)
@@ -3290,8 +3301,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;
@@ -3369,6 +3382,43 @@
          *     ECPoint      public;
          * } ServerECDHParams;
          */
+
+#if defined(MBEDTLS_USE_TINYCRYPT)
+        uECC_set_rng( &mbetls_uecc_rng_wrapper );
+
+        if( ssl->handshake->curve_tls_id != 23 )
+            return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
+
+        if( !uECC_make_key( ssl->handshake->ecdh_ownpubkey,
+                            ssl->handshake->ecdh_privkey,
+                            uecc_curve ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "Key creation failed" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        /*
+         * First byte is curve_type, always named_curve
+         */
+        ssl->out_msg[ssl->out_msglen++] = MBEDTLS_ECP_TLS_NAMED_CURVE;
+
+        /*
+        * Next two bytes are the namedcurve value
+        */
+        ssl->out_msg[ssl->out_msglen++] = ssl->handshake->curve_tls_id >> 8;
+        ssl->out_msg[ssl->out_msglen++] = ssl->handshake->curve_tls_id & 0xFF;
+
+        /*  Write the public key length */
+        ssl->out_msg[ssl->out_msglen++] = 2*NUM_ECC_BYTES;
+
+        memcpy( &ssl->out_msg[ssl->out_msglen],
+                ssl->handshake->ecdh_ownpubkey,
+                2*NUM_ECC_BYTES );
+
+        ssl->out_msglen += 2*NUM_ECC_BYTES;
+
+#else /* MBEDTLS_USE_TINYCRYPT */
+
         const mbedtls_ecp_curve_info *curve =
             mbedtls_ecp_curve_info_from_tls_id( ssl->handshake->curve_tls_id );
         int ret;
@@ -3407,6 +3457,9 @@
 
         MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
                                 MBEDTLS_DEBUG_ECDH_Q );
+
+#endif /* MBEDTLS_USE_TINYCRYPT */
+
     }
 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */
 
@@ -4140,6 +4193,26 @@
     }
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_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();
+
+        /* TODO: Parse the client's key share. */
+
+        if( !uECC_shared_secret( ssl->handshake->ecdh_peerkey,
+                                 ssl->handshake->ecdh_privkey,
+                                 ssl->handshake->premaster,
+                                 uecc_curve ) )
+        {
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+    }
+    else
+#endif
 #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
     defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 2a50db6..a1c26d0 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -12165,6 +12165,13 @@
     }
 }
 
+#if defined(MBEDTLS_USE_TINYCRYPT)
+int mbetls_uecc_rng_wrapper( uint8_t *dest, unsigned int size )
+{
+    return( mbedtls_ssl_conf_rng_func( NULL, dest, size ) );
+}
+#endif /* MBEDTLS_USE_TINYCRYPT */
+
 #if defined(MBEDTLS_ECP_C)
 /*
  * Check if a curve proposed by the peer is in our list.