Fix ECDSA hash selection bug with TLS 1.0 and 1.1
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 38b4029..29e9316 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1185,7 +1185,6 @@
                                           unsigned char **p,
                                           unsigned char *end,
                                           md_type_t *md_alg,
-                                          size_t *hash_len,
                                           pk_type_t *pk_alg )
 {
     ((void) ssl);
@@ -1195,16 +1194,12 @@
     /* Only in TLS 1.2 */
     if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
     {
-        *hash_len = 36;
         return( 0 );
     }
 
     if( (*p) + 2 > end )
         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
 
-    /* Info from md_alg will be used instead */
-    *hash_len = 0;
-
     /*
      * Get hash algorithm
      */
@@ -1361,7 +1356,7 @@
          * Handle the digitally-signed structure
          */
         if( ssl_parse_signature_algorithm( ssl, &p, end,
-                                           &md_alg, &hashlen, &pk_alg ) != 0 )
+                                           &md_alg, &pk_alg ) != 0 )
         {
             SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
             return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
@@ -1380,6 +1375,13 @@
             pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
         }
 
+        /* Default hash for ECDSA is SHA-1 */
+        if( pk_alg == POLARSSL_PK_ECDSA && md_alg == POLARSSL_MD_NONE )
+            md_alg = POLARSSL_MD_SHA1;
+
+        /*
+         * Read signature
+         */
         sig_len = ( p[0] << 8 ) | p[1];
         p += 2;
 
@@ -1389,14 +1391,18 @@
             return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
         }
 
+        SSL_DEBUG_BUF( 3, "signature", p, sig_len );
+
         /*
          * Compute the hash that has been signed
          */
-        if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
+        if( md_alg == POLARSSL_MD_NONE )
         {
             md5_context md5;
             sha1_context sha1;
 
+            hashlen = 36;
+
             /*
              * digitally-signed struct {
              *     opaque md5_hash[16];
@@ -1424,6 +1430,9 @@
         {
             md_context_t ctx;
 
+            /* Info from md_alg will be used instead */
+            hashlen = 0;
+
             /*
              * digitally-signed struct {
              *     opaque client_random[32];
@@ -1918,6 +1927,7 @@
     const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
     size_t n = 0, offset = 0;
     unsigned char hash[48];
+    unsigned char *hash_start = hash;
     md_type_t md_alg = POLARSSL_MD_NONE;
     unsigned int hashlen;
 
@@ -1965,6 +1975,16 @@
          */
         hashlen = 36;
         md_alg = POLARSSL_MD_NONE;
+
+        /*
+         * For ECDSA, default hash is SHA-1 only
+         */
+        if( pk_can_do( ssl->pk_key, POLARSSL_PK_ECDSA ) )
+        {
+            hash_start += 16;
+            hashlen -= 16;
+            md_alg = POLARSSL_MD_SHA1;
+        }
     }
     else
     {
@@ -2002,7 +2022,7 @@
         offset = 2;
     }
 
-    if( ( ret = pk_sign( ssl->pk_key, md_alg, hash, hashlen,
+    if( ( ret = pk_sign( ssl->pk_key, md_alg, hash_start, hashlen,
                          ssl->out_msg + 6 + offset, &n,
                          ssl->f_rng, ssl->p_rng ) ) != 0 )
     {
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index ce45898..8efd57e 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1951,9 +1951,33 @@
         size_t signature_len = 0;
 
         /*
+         * Choose hash algorithm. NONE means MD5 + SHA1 here.
+         */
+        if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
+        {
+            md_alg = ssl_md_alg_from_hash( ssl->handshake->sig_alg );
+
+            if( md_alg == POLARSSL_MD_NONE )
+            {
+                SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+                return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+            }
+        }
+        else if ( ciphersuite_info->key_exchange ==
+                  POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA )
+        {
+            md_alg = POLARSSL_MD_SHA1;
+        }
+        else
+        {
+            md_alg = POLARSSL_MD_NONE;
+        }
+
+
+        /*
          * Compute the hash to be signed
          */
-        if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
+        if( md_alg == POLARSSL_MD_NONE )
         {
             md5_context md5;
             sha1_context sha1;
@@ -1982,7 +2006,6 @@
             sha1_finish( &sha1, hash + 16 );
 
             hashlen = 36;
-            md_alg = POLARSSL_MD_NONE;
         }
         else
         {
@@ -1998,13 +2021,6 @@
              *     ServerDHParams params;
              * };
              */
-            if( ( md_alg = ssl_md_alg_from_hash( ssl->handshake->sig_alg ) )
-                         == POLARSSL_MD_NONE )
-            {
-                SSL_DEBUG_MSG( 1, ( "should never happen" ) );
-                return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
-            }
-
             if( ( ret = md_init_ctx( &ctx, md_info_from_type(md_alg) ) ) != 0 )
             {
                 SSL_DEBUG_RET( 1, "md_init_ctx", ret );
@@ -2498,6 +2514,7 @@
     int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
     size_t sa_len, sig_len;
     unsigned char hash[48];
+    unsigned char *hash_start = hash;
     size_t hashlen;
     pk_type_t pk_alg;
     md_type_t md_alg;
@@ -2556,6 +2573,15 @@
 
         md_alg = POLARSSL_MD_NONE;
         hashlen = 36;
+
+        /* For ECDSA, use SHA-1, not MD-5 + SHA-1 */
+        if( pk_can_do( &ssl->session_negotiate->peer_cert->pk,
+                        POLARSSL_PK_ECDSA ) )
+        {
+            hash_start += 16;
+            hashlen -= 16;
+            md_alg = POLARSSL_MD_SHA1;
+        }
     }
     else
     {
@@ -2607,7 +2633,7 @@
     }
 
     if( ( ret = pk_verify( &ssl->session_negotiate->peer_cert->pk,
-                           md_alg, hash, hashlen,
+                           md_alg, hash_start, hashlen,
                            ssl->in_msg + 6 + sa_len, sig_len ) ) != 0 )
     {
         SSL_DEBUG_RET( 1, "pk_verify", ret );