gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, master, updated. gnutls_2_99_1-51-g6bfd33b


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_2_99_1-51-g6bfd33b
Date: Sat, 21 May 2011 07:24:03 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=6bfd33b21877d02b2fe81fd5629d604976f460c8

The branch, master has been updated
       via  6bfd33b21877d02b2fe81fd5629d604976f460c8 (commit)
       via  b15e6df17495c07a25ce24a00c0ec563206c6c41 (commit)
       via  82b4d443a063c3402fc073297d053d8dbcc85582 (commit)
       via  e12ca68abcdc41f1f4bb7ce55219b7cb11c3193b (commit)
       via  e03cc3039f45368e9971f117367ca4a56fe364cc (commit)
       via  8d69e1bd9e61cc0b390ca987fd66ec2aad9c0d3c (commit)
       via  96a87b6029804f7b0e5970e3c67140822205b181 (commit)
      from  2bd4123f0ad3b694e8cfadc15d0fe1b16e36bc49 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 6bfd33b21877d02b2fe81fd5629d604976f460c8
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat May 21 09:23:48 2011 +0200

    Added support for ECDHE-RSA ciphersuites.

commit b15e6df17495c07a25ce24a00c0ec563206c6c41
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat May 21 09:13:49 2011 +0200

    inlined function to avoid gcc warnings

commit 82b4d443a063c3402fc073297d053d8dbcc85582
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat May 21 08:29:58 2011 +0200

    Added previous code that was fixed for y^2 = x^3 - 3x + b, because all secg 
curves have a fixed to -3.
    Simplified file naming scheme.

commit e12ca68abcdc41f1f4bb7ce55219b7cb11c3193b
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat May 21 08:15:48 2011 +0200

    Added SECP224R1.

commit e03cc3039f45368e9971f117367ca4a56fe364cc
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat May 21 08:15:15 2011 +0200

    updates to benchmarks.

commit 8d69e1bd9e61cc0b390ca987fd66ec2aad9c0d3c
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri May 20 21:41:24 2011 +0200

    Added curve SECP512R1.

commit 96a87b6029804f7b0e5970e3c67140822205b181
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri May 20 21:32:58 2011 +0200

    benchmark ECDH and DH.

-----------------------------------------------------------------------

Summary of changes:
 lib/auth/anon_ecdh.c                               |   14 +-
 lib/auth/dh_common.c                               |    1 +
 lib/auth/dhe.c                                     |   82 ++++--
 lib/auth/ecdh_common.c                             |   13 +-
 lib/gnutls_algorithms.c                            |   55 ++++-
 lib/gnutls_global.c                                |    5 -
 lib/gnutls_handshake.c                             |    3 +-
 lib/gnutls_int.h                                   |    2 +
 lib/gnutls_priority.c                              |    1 +
 lib/gnutls_state.c                                 |   21 ++
 lib/gnutls_state.h                                 |    2 +
 lib/includes/gnutls/gnutls.h.in                    |    2 +
 lib/nettle/Makefile.am                             |    6 +-
 lib/nettle/ecc.h                                   |    8 +-
 lib/nettle/ecc_free.c                              |    5 +-
 lib/nettle/ecc_make_key.c                          |    5 +-
 lib/nettle/{ltc_ecc_map.c => ecc_map.c}            |    6 +-
 lib/nettle/{ltc_ecc_mulmod.c => ecc_mulmod.c}      |    5 +-
 lib/nettle/{ltc_ecc_points.c => ecc_points.c}      |    5 +-
 ...tive_add_point.c => ecc_projective_add_point.c} |    6 +-
 ...tive_dbl_point.c => ecc_projective_dbl_point.c} |   75 +++--
 lib/nettle/ecc_projective_dbl_point_3.c            |  148 ++++++++++
 lib/nettle/ecc_shared_secret.c                     |    5 +-
 lib/nettle/ecc_sign_hash.c                         |    5 +-
 lib/nettle/ecc_test.c                              |    8 +-
 lib/nettle/ecc_verify_hash.c                       |    5 +-
 src/Makefile.am                                    |    8 +-
 src/{benchmark.c => benchmark-cipher.c}            |    6 +-
 src/benchmark-common.c                             |  123 --------
 src/benchmark-tls.c                                |   88 ++++++-
 src/benchmark.c                                    |  305 +++++++-------------
 src/benchmark.h                                    |    2 +-
 tests/eagain-common.h                              |    2 +-
 33 files changed, 567 insertions(+), 460 deletions(-)
 rename lib/nettle/{ltc_ecc_map.c => ecc_map.c} (94%)
 rename lib/nettle/{ltc_ecc_mulmod.c => ecc_mulmod.c} (98%)
 rename lib/nettle/{ltc_ecc_points.c => ecc_points.c} (94%)
 rename lib/nettle/{ltc_ecc_projective_add_point.c => 
ecc_projective_add_point.c} (96%)
 rename lib/nettle/{ltc_ecc_projective_dbl_point.c => 
ecc_projective_dbl_point.c} (72%)
 create mode 100644 lib/nettle/ecc_projective_dbl_point_3.c
 copy src/{benchmark.c => benchmark-cipher.c} (98%)
 delete mode 100644 src/benchmark-common.c

diff --git a/lib/auth/anon_ecdh.c b/lib/auth/anon_ecdh.c
index 5e9932f..e87f80c 100644
--- a/lib/auth/anon_ecdh.c
+++ b/lib/auth/anon_ecdh.c
@@ -66,7 +66,6 @@ const mod_auth_st anon_ecdh_auth_struct = {
 static int
 gen_anon_ecdh_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
-  ecc_curve_t curve;
   int ret;
   gnutls_anon_server_credentials_t cred;
 
@@ -78,10 +77,6 @@ gen_anon_ecdh_server_kx (gnutls_session_t session, 
gnutls_buffer_st* data)
       return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
     }
 
-  curve = _gnutls_session_ecc_curve_get(session);
-  if (curve == GNUTLS_ECC_CURVE_INVALID)
-    return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES);
-  
   if ((ret =
        _gnutls_auth_info_set (session, GNUTLS_CRD_ANON,
                               sizeof (anon_auth_info_st), 1)) < 0)
@@ -90,7 +85,7 @@ gen_anon_ecdh_server_kx (gnutls_session_t session, 
gnutls_buffer_st* data)
       return ret;
     }
 
-  ret = _gnutls_ecdh_common_print_server_kx (session, data, curve);
+  ret = _gnutls_ecdh_common_print_server_kx (session, data, 
_gnutls_session_ecc_curve_get(session));
   if (ret < 0)
     {
       gnutls_assert ();
@@ -105,7 +100,6 @@ proc_anon_ecdh_client_kx (gnutls_session_t session, opaque 
* data,
                      size_t _data_size)
 {
   gnutls_anon_server_credentials_t cred;
-  ecc_curve_t curve;
 
   cred = (gnutls_anon_server_credentials_t)
     _gnutls_get_cred (session->key, GNUTLS_CRD_ANON, NULL);
@@ -115,11 +109,7 @@ proc_anon_ecdh_client_kx (gnutls_session_t session, opaque 
* data,
       return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
     }
 
-  curve = _gnutls_session_ecc_curve_get(session);
-  if (curve == GNUTLS_ECC_CURVE_INVALID)
-    return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES);
-
-  return _gnutls_proc_ecdh_common_client_kx (session, data, _data_size, curve);
+  return _gnutls_proc_ecdh_common_client_kx (session, data, _data_size, 
_gnutls_session_ecc_curve_get(session));
 }
 
 int
diff --git a/lib/auth/dh_common.c b/lib/auth/dh_common.c
index d5c3506..f887af6 100644
--- a/lib/auth/dh_common.c
+++ b/lib/auth/dh_common.c
@@ -202,6 +202,7 @@ error:
   return ret;
 }
 
+/* Returns the bytes parsed */
 int
 _gnutls_proc_dh_common_server_kx (gnutls_session_t session,
                                   opaque * data, size_t _data_size, int psk)
diff --git a/lib/auth/dhe.c b/lib/auth/dhe.c
index c8badfe..a261576 100644
--- a/lib/auth/dhe.c
+++ b/lib/auth/dhe.c
@@ -40,11 +40,29 @@
 #include <gnutls_x509.h>
 #include <gnutls_state.h>
 #include <auth/dh_common.h>
+#include <auth/ecdh_common.h>
 
 static int gen_dhe_server_kx (gnutls_session_t, gnutls_buffer_st*);
 static int proc_dhe_server_kx (gnutls_session_t, opaque *, size_t);
 static int proc_dhe_client_kx (gnutls_session_t, opaque *, size_t);
 
+const mod_auth_st ecdhe_rsa_auth_struct = {
+  "ECDHE_RSA",
+  _gnutls_gen_cert_server_certificate,
+  _gnutls_gen_cert_client_certificate,
+  gen_dhe_server_kx,
+  _gnutls_gen_ecdh_common_client_kx,   /* This is the only different */
+  _gnutls_gen_cert_client_cert_vrfy,
+  _gnutls_gen_cert_server_cert_req,
+
+  _gnutls_proc_cert_server_certificate,
+  _gnutls_proc_cert_client_certificate,
+  proc_dhe_server_kx,
+  proc_dhe_client_kx,
+  _gnutls_proc_cert_client_cert_vrfy,
+  _gnutls_proc_cert_cert_req
+};
+
 const mod_auth_st dhe_rsa_auth_struct = {
   "DHE_RSA",
   _gnutls_gen_cert_server_certificate,
@@ -112,18 +130,6 @@ gen_dhe_server_kx (gnutls_session_t session, 
gnutls_buffer_st* data)
       return ret;
     }
 
-  dh_params =
-    _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
-  mpis = _gnutls_dh_params_to_mpi (dh_params);
-  if (mpis == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
-    }
-
-  p = mpis[0];
-  g = mpis[1];
-
   if ((ret = _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
                                     sizeof (cert_auth_info_st), 0)) < 0)
     {
@@ -131,9 +137,29 @@ gen_dhe_server_kx (gnutls_session_t session, 
gnutls_buffer_st* data)
       return ret;
     }
 
-  _gnutls_dh_set_group (session, g, p);
+  if (!_gnutls_session_is_ecc (session))
+    {
+      dh_params =
+        _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
+      mpis = _gnutls_dh_params_to_mpi (dh_params);
+      if (mpis == NULL)
+        {
+          gnutls_assert ();
+          return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
+        }
+
+      p = mpis[0];
+      g = mpis[1];
+
+      _gnutls_dh_set_group (session, g, p);
+
+      ret = _gnutls_dh_common_print_server_kx (session, g, p, data, 0);
+    }
+  else
+    {
+      ret = _gnutls_ecdh_common_print_server_kx (session, data, 
_gnutls_session_ecc_curve_get(session));
+    }
 
-  ret = _gnutls_dh_common_print_server_kx (session, g, p, data, 0);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -229,7 +255,11 @@ proc_dhe_server_kx (gnutls_session_t session, opaque * 
data,
       return GNUTLS_E_INTERNAL_ERROR;
     }
 
-  ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size, 0);
+  if (!_gnutls_session_is_ecc (session))
+    ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size, 0);
+  else
+    ret = _gnutls_proc_ecdh_common_server_kx (session, data, _data_size);
+
   if (ret < 0)
     {
       gnutls_assert ();
@@ -309,19 +339,21 @@ proc_dhe_client_kx (gnutls_session_t session, opaque * 
data,
       return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
     }
 
-  dh_params =
-    _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
-  mpis = _gnutls_dh_params_to_mpi (dh_params);
-  if (mpis == NULL)
+  if (!_gnutls_session_is_ecc (session))
     {
-      gnutls_assert ();
-      return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
-    }
+      dh_params =
+        _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
+      mpis = _gnutls_dh_params_to_mpi (dh_params);
+      if (mpis == NULL)
+        return gnutls_assert_val(GNUTLS_E_NO_TEMPORARY_DH_PARAMS);
 
-  p = mpis[0];
-  g = mpis[1];
+      p = mpis[0];
+      g = mpis[1];
 
-  ret = _gnutls_proc_dh_common_client_kx (session, data, _data_size, g, p);
+      ret = _gnutls_proc_dh_common_client_kx (session, data, _data_size, g, p);
+    }
+  else
+    ret = _gnutls_proc_ecdh_common_client_kx (session, data, _data_size, 
_gnutls_session_ecc_curve_get(session));
 
   return ret;
 
diff --git a/lib/auth/ecdh_common.c b/lib/auth/ecdh_common.c
index 502396d..e4440c1 100644
--- a/lib/auth/ecdh_common.c
+++ b/lib/auth/ecdh_common.c
@@ -81,6 +81,9 @@ _gnutls_proc_ecdh_common_client_kx (gnutls_session_t session,
   int ret, i = 0;
   int point_size;
 
+  if (curve == GNUTLS_ECC_CURVE_INVALID)
+    return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES);
+
   DECR_LEN (data_size, 1);
   point_size = data[i];
   i+=1;
@@ -130,6 +133,7 @@ _gnutls_gen_ecdh_common_client_kx (gnutls_session_t 
session, gnutls_buffer_st* d
   return data->length;
 }
 
+/* Returns the bytes parsed */
 int
 _gnutls_proc_ecdh_common_server_kx (gnutls_session_t session,
                                   opaque * data, size_t _data_size)
@@ -155,14 +159,16 @@ _gnutls_proc_ecdh_common_server_kx (gnutls_session_t 
session,
 
   DECR_LEN (data_size, 1);
   point_size = data[i];
-  i+=1;
+  i++;
 
   DECR_LEN (data_size, point_size);
   ret = _gnutls_ecc_ansi_x963_import(curve, &data[i], point_size, 
&session->key->ecdh_x, &session->key->ecdh_y);
   if (ret < 0)
     return gnutls_assert_val(ret);
 
-  return ret;
+  i+=point_size;
+
+  return i;
 }
 
 /* If the psk flag is set, then an empty psk_identity_hint will
@@ -174,6 +180,9 @@ int _gnutls_ecdh_common_print_server_kx (gnutls_session_t 
session, gnutls_buffer
   int ret;
   gnutls_datum_t out;
 
+  if (curve == GNUTLS_ECC_CURVE_INVALID)
+    return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES);
+
   /* curve type */
   p = 3;
   
diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c
index f66164e..df9d1e6 100644
--- a/lib/gnutls_algorithms.c
+++ b/lib/gnutls_algorithms.c
@@ -73,6 +73,7 @@ static const gnutls_cred_map cred_mappings[] = {
   {GNUTLS_KX_ANON_ECDH, GNUTLS_CRD_ANON, GNUTLS_CRD_ANON},
   {GNUTLS_KX_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
   {GNUTLS_KX_RSA_EXPORT, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
+  {GNUTLS_KX_ECDHE_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
   {GNUTLS_KX_DHE_DSS, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
   {GNUTLS_KX_DHE_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
   {GNUTLS_KX_PSK, GNUTLS_CRD_PSK, GNUTLS_CRD_PSK},
@@ -114,6 +115,7 @@ static const gnutls_pk_map pk_mappings[] = {
   {GNUTLS_KX_RSA_EXPORT, GNUTLS_PK_RSA, CIPHER_SIGN},
   {GNUTLS_KX_DHE_RSA, GNUTLS_PK_RSA, CIPHER_SIGN},
   {GNUTLS_KX_SRP_RSA, GNUTLS_PK_RSA, CIPHER_SIGN},
+  {GNUTLS_KX_ECDHE_RSA, GNUTLS_PK_RSA, CIPHER_SIGN},
   {GNUTLS_KX_DHE_DSS, GNUTLS_PK_DSA, CIPHER_SIGN},
   {GNUTLS_KX_SRP_DSS, GNUTLS_PK_DSA, CIPHER_SIGN},
   {0, 0, 0}
@@ -259,6 +261,7 @@ static const gnutls_hash_entry hash_algorithms[] = {
 extern mod_auth_st rsa_auth_struct;
 extern mod_auth_st rsa_export_auth_struct;
 extern mod_auth_st dhe_rsa_auth_struct;
+extern mod_auth_st ecdhe_rsa_auth_struct;
 extern mod_auth_st dhe_dss_auth_struct;
 extern mod_auth_st anon_auth_struct;
 extern mod_auth_st anon_ecdh_auth_struct;
@@ -287,6 +290,7 @@ static const gnutls_kx_algo_entry _gnutls_kx_algorithms[] = 
{
   {"RSA-EXPORT", GNUTLS_KX_RSA_EXPORT, &rsa_export_auth_struct, 0,
    1 /* needs RSA params */ },
   {"DHE-RSA", GNUTLS_KX_DHE_RSA, &dhe_rsa_auth_struct, 1, 0},
+  {"ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, &ecdhe_rsa_auth_struct, 1, 0},
   {"DHE-DSS", GNUTLS_KX_DHE_DSS, &dhe_dss_auth_struct, 1, 0},
 
 #ifdef ENABLE_SRP
@@ -467,10 +471,17 @@ typedef struct
 #define GNUTLS_DHE_PSK_NULL_SHA256 { 0x00, 0xB4 }
 
 /* ECC */
+#define GNUTLS_ECDH_ANON_NULL_SHA { 0xC0, 0x15 }
 #define GNUTLS_ECDH_ANON_3DES_EDE_CBC_SHA { 0xC0, 0x17 }
 #define GNUTLS_ECDH_ANON_AES_128_CBC_SHA { 0xC0, 0x18 }
 #define GNUTLS_ECDH_ANON_AES_256_CBC_SHA { 0xC0, 0x19 }
 
+/* ECC-RSA */
+#define GNUTLS_ECDHE_RSA_NULL_SHA { 0xC0, 0x10 }
+#define GNUTLS_ECDHE_RSA_3DES_EDE_CBC_SHA { 0xC0, 0x12 }
+#define GNUTLS_ECDHE_RSA_AES_128_CBC_SHA { 0xC0, 0x13 }
+#define GNUTLS_ECDHE_RSA_AES_256_CBC_SHA { 0xC0, 0x14 }
+
 
 #define CIPHER_SUITES_COUNT 
sizeof(cs_algorithms)/sizeof(gnutls_cipher_suite_entry)-1
 
@@ -769,6 +780,10 @@ static const gnutls_cipher_suite_entry cs_algorithms[] = {
                              GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
                              GNUTLS_VERSION_MAX, 1),
 /* ECC-ANON */
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDH_ANON_NULL_SHA,
+                             GNUTLS_CIPHER_NULL, GNUTLS_KX_ANON_ECDH,
+                             GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDH_ANON_3DES_EDE_CBC_SHA,
                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_ANON_ECDH,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
@@ -781,7 +796,23 @@ static const gnutls_cipher_suite_entry cs_algorithms[] = {
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_ANON_ECDH,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
                              GNUTLS_VERSION_MAX, 1),
-
+/* ECC-RSA */
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_RSA_NULL_SHA,
+                             GNUTLS_CIPHER_NULL, GNUTLS_KX_ECDHE_RSA,
+                             GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_RSA_3DES_EDE_CBC_SHA,
+                             GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_ECDHE_RSA,
+                             GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_RSA_AES_128_CBC_SHA,
+                             GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ECDHE_RSA,
+                             GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_RSA_AES_256_CBC_SHA,
+                             GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_ECDHE_RSA,
+                             GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
   {0, {{0, 0}}, 0, 0, 0, 0, 0, 0}
 };
 
@@ -2199,6 +2230,17 @@ _gnutls_sign_to_tls_aid (gnutls_sign_algorithm_t sign)
 
 static const gnutls_ecc_curve_entry_st ecc_curves[] = {
   {
+    .name = "SECP224R1", 
+    .id = GNUTLS_ECC_CURVE_SECP224R1,
+    .size = 28,
+    .prime = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
+    .A = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
+    .B = "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
+    .order = "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
+    .Gx =    "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
+    .Gy =    "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
+  },
+  {
     .name = "SECP256R1", 
     .id = GNUTLS_ECC_CURVE_SECP256R1,
     .size = 32,
@@ -2220,6 +2262,17 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = {
     .Gx = 
"AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
     .Gy = 
"3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"
   },
+  {
+    .name = "SECP521R1",
+    .id = GNUTLS_ECC_CURVE_SECP521R1,
+    .size = 66,
+    .prime = 
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+    .A = 
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
+    .B = 
"0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
+    .order = 
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
+    .Gx =    
"00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
+    .Gy =    
"011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
+  },
   {0, 0, 0}
 };
 
diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c
index 483d245..15bf0cd 100644
--- a/lib/gnutls_global.c
+++ b/lib/gnutls_global.c
@@ -155,8 +155,6 @@ gnutls_global_set_mem_functions (gnutls_alloc_function 
alloc_func,
 }
 
 static int _gnutls_init = 0;
-int ecc_test(void);
-
 
 /**
  * gnutls_global_init:
@@ -196,9 +194,6 @@ gnutls_global_init (void)
   if (_gnutls_init++)
     goto out;
 
-res = ecc_test();
-if (res != 0) exit(1);
-    
   if (gl_sockets_startup (SOCKETS_1_1))
     return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
 
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 7599874..c262f6f 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -3348,7 +3348,8 @@ _gnutls_remove_unwanted_ciphersuites (gnutls_session_t 
session,
       /* If we have not agreed to a common curve with the peer don't bother
        * negotiating ECDH.
        */
-      if (session->security_parameters.entity == GNUTLS_SERVER && (kx == 
GNUTLS_KX_ANON_ECDH))
+      if (session->security_parameters.entity == GNUTLS_SERVER && (kx == 
GNUTLS_KX_ANON_ECDH ||
+          kx == GNUTLS_KX_ECDHE_RSA))
         {
           if (_gnutls_session_ecc_curve_get(session) == 
GNUTLS_ECC_CURVE_INVALID)
             delete = 1;
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index d67bddb..8dbec24 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -228,8 +228,10 @@ typedef enum extensions_t
 typedef enum
 {
   GNUTLS_ECC_CURVE_INVALID=0,
+  GNUTLS_ECC_CURVE_SECP224R1,
   GNUTLS_ECC_CURVE_SECP256R1,
   GNUTLS_ECC_CURVE_SECP384R1,
+  GNUTLS_ECC_CURVE_SECP521R1,
 } ecc_curve_t;
 
 typedef enum
diff --git a/lib/gnutls_priority.c b/lib/gnutls_priority.c
index c06a22d..501c1a2 100644
--- a/lib/gnutls_priority.c
+++ b/lib/gnutls_priority.c
@@ -218,6 +218,7 @@ gnutls_certificate_type_set_priority (gnutls_session_t 
session,
 static const int supported_ecc_default[] = {
   GNUTLS_ECC_CURVE_SECP256R1,
   GNUTLS_ECC_CURVE_SECP384R1,
+  GNUTLS_ECC_CURVE_SECP521R1,
   0
 };
 
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index ab4d9d0..c8c83b8 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -1176,6 +1176,27 @@ _gnutls_session_is_psk (gnutls_session_t session)
   return 0;
 }
 
+/*-
+ * _gnutls_session_is_ecc - Used to check whether this session uses ECC kx
+ * @session: is a #gnutls_session_t structure.
+ *
+ * This function will return non zero if this session uses an elliptic
+ * curves key exchange exchange algorithm.
+ -*/
+int
+_gnutls_session_is_ecc (gnutls_session_t session)
+{
+  gnutls_kx_algorithm_t kx;
+
+  kx =
+    _gnutls_cipher_suite_get_kx_algo (&session->
+                                      
security_parameters.current_cipher_suite);
+  if (kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ANON_ECDH)
+    return 1;
+
+  return 0;
+}
+
 /**
  * gnutls_session_get_ptr:
  * @session: is a #gnutls_session_t structure.
diff --git a/lib/gnutls_state.h b/lib/gnutls_state.h
index edd4b0d..7e51463 100644
--- a/lib/gnutls_state.h
+++ b/lib/gnutls_state.h
@@ -36,6 +36,8 @@ inline static ecc_curve_t 
_gnutls_session_ecc_curve_get(gnutls_session_t session
   return session->security_parameters.ecc_curve;
 }
 
+int _gnutls_session_is_ecc (gnutls_session_t session);
+
 void
 _gnutls_session_ecc_curve_set (gnutls_session_t session,
                                ecc_curve_t c);
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 053970f..0a08825 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -128,6 +128,7 @@ extern "C"
    * @GNUTLS_KX_RSA: RSA key-exchange algorithm.
    * @GNUTLS_KX_DHE_DSS: DHE-DSS key-exchange algorithm.
    * @GNUTLS_KX_DHE_RSA: DHE-RSA key-exchange algorithm.
+   * @GNUTLS_KX_ECDHE_RSA: ECDHE-RSA key-exchange algorithm.
    * @GNUTLS_KX_ANON_DH: Anon-DH key-exchange algorithm.
    * @GNUTLS_KX_ANON_ECDH: Anon-ECDH key-exchange algorithm.
    * @GNUTLS_KX_SRP: SRP key-exchange algorithm.
@@ -153,6 +154,7 @@ extern "C"
     GNUTLS_KX_PSK = 9,
     GNUTLS_KX_DHE_PSK = 10,
     GNUTLS_KX_ANON_ECDH = 11,
+    GNUTLS_KX_ECDHE_RSA = 12,
   } gnutls_kx_algorithm_t;
 
   /**
diff --git a/lib/nettle/Makefile.am b/lib/nettle/Makefile.am
index 0516800..a4bd44c 100644
--- a/lib/nettle/Makefile.am
+++ b/lib/nettle/Makefile.am
@@ -36,7 +36,7 @@ noinst_LTLIBRARIES = libcrypto.la
 
 libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c rnd.c init.c egd.c egd.h \
        multi.c ecc_free.c ecc.h ecc_make_key.c ecc_shared_secret.c \
-       ecc_test.c ltc_ecc_map.c \
-       ltc_ecc_mulmod.c ltc_ecc_points.c \
-       ltc_ecc_projective_add_point.c ltc_ecc_projective_dbl_point.c \
+       ecc_test.c ecc_map.c \
+       ecc_mulmod.c ecc_points.c ecc_projective_dbl_point_3.c \
+       ecc_projective_add_point.c ecc_projective_dbl_point.c \
        mp_unsigned_bin.c ecc_sign_hash.c ecc_verify_hash.c 
diff --git a/lib/nettle/ecc.h b/lib/nettle/ecc.h
index 9024294..56fafc8 100644
--- a/lib/nettle/ecc.h
+++ b/lib/nettle/ecc.h
@@ -6,8 +6,12 @@
 #include <string.h>
 #include <assert.h>
 
-#define LTC_MECC
-#define ECC256
+/* assume y^2 = x^3 - 3x + b
+ * instead of the generic y^2 = x^3 + ax + b
+ *
+ * (XXX: the generic case has not been tested)
+ */
+#define ECC_SECP_CURVES_ONLY
 
 #define PK_PRIVATE 1
 #define PK_PUBLIC 2
diff --git a/lib/nettle/ecc_free.c b/lib/nettle/ecc_free.c
index a4bf451..bbf087d 100644
--- a/lib/nettle/ecc_free.c
+++ b/lib/nettle/ecc_free.c
@@ -9,7 +9,7 @@
  * Tom St Denis, address@hidden, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
   Free an ECC key from memory
   @param key   The key you wish to free
@@ -35,7 +33,6 @@ ecc_free (ecc_key * key)
                   &key->prime, &key->order, &key->Gx, &key->Gy, NULL);
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_free.c,v $ */
 /* $Revision: 1.6 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
diff --git a/lib/nettle/ecc_make_key.c b/lib/nettle/ecc_make_key.c
index f1e5cde..aab6fed 100644
--- a/lib/nettle/ecc_make_key.c
+++ b/lib/nettle/ecc_make_key.c
@@ -9,7 +9,7 @@
  * Tom St Denis, address@hidden, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
   Make a new ECC key 
   @param prng         An active PRNG state
@@ -146,7 +144,6 @@ cleanup:
   return err;
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_make_key.c,v $ */
 /* $Revision: 1.13 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
diff --git a/lib/nettle/ltc_ecc_map.c b/lib/nettle/ecc_map.c
similarity index 94%
rename from lib/nettle/ltc_ecc_map.c
rename to lib/nettle/ecc_map.c
index dca353b..bbe99ec 100644
--- a/lib/nettle/ltc_ecc_map.c
+++ b/lib/nettle/ecc_map.c
@@ -9,7 +9,7 @@
  * Tom St Denis, address@hidden, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
   Map a projective jacobian point back to affine space
   @param P        [in/out] The point to map
@@ -67,8 +65,6 @@ ltc_ecc_map (ecc_point * P, mpz_t modulus)
   return err;
 }
 
-#endif
-
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_map.c,v $ */
 /* $Revision: 1.7 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
diff --git a/lib/nettle/ltc_ecc_mulmod.c b/lib/nettle/ecc_mulmod.c
similarity index 98%
rename from lib/nettle/ltc_ecc_mulmod.c
rename to lib/nettle/ecc_mulmod.c
index f8c02dc..1236dc3 100644
--- a/lib/nettle/ltc_ecc_mulmod.c
+++ b/lib/nettle/ecc_mulmod.c
@@ -9,7 +9,7 @@
  * Tom St Denis, address@hidden, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
    Perform a point multiplication  (timing resistant)
    @param k    The scalar to multiply by
@@ -182,7 +180,6 @@ done:
   return err;
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod_timing.c,v $ */
 /* $Revision: 1.13 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
diff --git a/lib/nettle/ltc_ecc_points.c b/lib/nettle/ecc_points.c
similarity index 94%
rename from lib/nettle/ltc_ecc_points.c
rename to lib/nettle/ecc_points.c
index e4e2cd4..fa9b5b5 100644
--- a/lib/nettle/ltc_ecc_points.c
+++ b/lib/nettle/ecc_points.c
@@ -9,7 +9,7 @@
  * Tom St Denis, address@hidden, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
    Allocate a new ECC point
    @return A newly allocated point or NULL on error 
@@ -58,7 +56,6 @@ ltc_ecc_del_point (ecc_point * p)
     }
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_points.c,v $ */
 /* $Revision: 1.7 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
diff --git a/lib/nettle/ltc_ecc_projective_add_point.c 
b/lib/nettle/ecc_projective_add_point.c
similarity index 96%
rename from lib/nettle/ltc_ecc_projective_add_point.c
rename to lib/nettle/ecc_projective_add_point.c
index 31bd679..dd98eb4 100644
--- a/lib/nettle/ltc_ecc_projective_add_point.c
+++ b/lib/nettle/ecc_projective_add_point.c
@@ -9,7 +9,7 @@
  * Tom St Denis, address@hidden, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC))
-
 /**
    Add two ECC points
    @param P        The point to add
@@ -204,8 +202,6 @@ ltc_ecc_projective_add_point (ecc_point * P, ecc_point * Q, 
ecc_point * R,
   return err;
 }
 
-#endif
-
 /* $Source: 
/cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c,v $ */
 /* $Revision: 1.16 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
diff --git a/lib/nettle/ltc_ecc_projective_dbl_point.c 
b/lib/nettle/ecc_projective_dbl_point.c
similarity index 72%
rename from lib/nettle/ltc_ecc_projective_dbl_point.c
rename to lib/nettle/ecc_projective_dbl_point.c
index 618f0d9..6d446c2 100644
--- a/lib/nettle/ltc_ecc_projective_dbl_point.c
+++ b/lib/nettle/ecc_projective_dbl_point.c
@@ -1,27 +1,32 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+/*
+ * Copyright (C) 2011 Free Software Foundation, Inc.
  *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
+ * Author: Nikos Mavrogiannopoulos
  *
- * The library is free for all purposes without any express
- * guarantee it works.
+ * This file is part of GNUTLS.
+ *
+ * The GNUTLS library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
  *
- * Tom St Denis, address@hidden, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
- *
- * All curves taken from NIST recommendation paper of July 1999
- * Available at http://csrc.nist.gov/cryptval/dss.htm
+/* Implements ECC point doubling over Z/pZ for curve y^2 = x^3 + ax + b
  */
 #include "ecc.h"
 
-/**
-  @file ltc_ecc_projective_dbl_point.c
-  ECC Crypto, Tom St Denis
-*/
-
-#if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC))
+#ifndef ECC_SECP_CURVES_ONLY
 
 /**
    Double an ECC point
@@ -42,6 +47,30 @@ ltc_ecc_projective_dbl_point (ecc_point * P, ecc_point * R, 
mpz_t a,
   assert (R != NULL);
   assert (modulus != NULL);
 
+  /*
+    algorithm used:
+     if (Y == 0)
+       return POINT_AT_INFINITY
+     S = 4*X*Y^2
+     M = 3*X^2 + a*Z^4
+     X' = M^2 - 2*S
+     Y' = M*(S - X') - 8*Y^4
+     Z' = 2*Y*Z
+     return (X', Y', Z')
+   */
+
+  if (mpz_cmp_ui(P->y, 0) == 0)
+    {
+      /* point at infinity 
+       * under jacobian coordinates
+       */
+      mpz_set(R->x, 1);
+      mpz_set(R->y, 1);
+      mpz_set(R->z, 0);
+      
+      return 0;
+    }
+
   if ((err = mp_init_multi (&t1, &m, &s, NULL)) != 0)
     {
       return err;
@@ -54,16 +83,6 @@ ltc_ecc_projective_dbl_point (ecc_point * P, ecc_point * R, 
mpz_t a,
       mpz_set (R->z, P->z);
     }
 
-  /*
-     if (Y == 0)
-     return POINT_AT_INFINITY
-     S = 4*X*Y^2
-     M = 3*X^2 + a*Z^4
-     X' = M^2 - 2*S
-     Y' = M*(S - X') - 8*Y^4
-     Z' = 2*Y*Z
-     return (X', Y', Z')
-   */
 
   /* m = Z * Z */
   mpz_mul (m, R->z, R->z);
@@ -187,7 +206,5 @@ ltc_ecc_projective_dbl_point (ecc_point * P, ecc_point * R, 
mpz_t a,
   mp_clear_multi (&t1, &m, &s, NULL);
   return err;
 }
+
 #endif
-/* $Source: 
/cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c,v $ */
-/* $Revision: 1.11 $ */
-/* $Date: 2007/05/12 14:32:35 $ */
diff --git a/lib/nettle/ecc_projective_dbl_point_3.c 
b/lib/nettle/ecc_projective_dbl_point_3.c
new file mode 100644
index 0000000..7c415fe
--- /dev/null
+++ b/lib/nettle/ecc_projective_dbl_point_3.c
@@ -0,0 +1,148 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, address@hidden, http://libtom.org
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "ecc.h"
+
+/**
+  @file ltc_ecc_projective_dbl_point.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef ECC_SECP_CURVES_ONLY
+
+/**
+   Double an ECC point
+   @param P   The point to double
+   @param R   [out] The destination of the double
+   @param modulus  The modulus of the field the ECC curve is in
+   @param mp       The "b" value from montgomery_setup()
+   @return 0 on success
+*/
+int
+ltc_ecc_projective_dbl_point (ecc_point * P, ecc_point * R, mpz_t a /* a is -3 
*/,
+                              mpz_t modulus)
+{
+   mpz_t t1, t2;
+   int   err;
+
+   assert(P       != NULL);
+   assert(R       != NULL);
+   assert(modulus != NULL);
+
+   if ((err = mp_init_multi(&t1, &t2, NULL)) != 0) {
+      return err;
+   }
+
+   if (P != R) {
+      mpz_set(R->x, P->x);
+      mpz_set(R->y, P->y);
+      mpz_set(R->z, P->z);
+   }
+
+   /* t1 = Z * Z */
+   mpz_mul(t1, R->z, R->z);
+   mpz_mod(t1, t1, modulus);
+   /* Z = Y * Z */
+   mpz_mul(R->z, R->y, R->z);
+   mpz_mod(R->z, R->z, modulus);
+   /* Z = 2Z */
+   mpz_add(R->z, R->z, R->z);
+   if (mpz_cmp(R->z, modulus) >= 0) {
+      mpz_sub(R->z, R->z, modulus);
+   }
+   
+   /* T2 = X - T1 */
+   mpz_sub(t2, R->x, t1);
+   if (mpz_cmp_ui(t2, 0) < 0) {
+      mpz_add(t2, t2, modulus);
+   }
+   /* T1 = X + T1 */
+   mpz_add(t1, t1, R->x);
+   if (mpz_cmp(t1, modulus) >= 0) {
+      mpz_sub(t1, t1, modulus);
+   }
+   /* T2 = T1 * T2 */
+   mpz_mul(t2, t1, t2);
+   mpz_mod(t2, t2, modulus);
+   /* T1 = 2T2 */
+   mpz_add(t1, t2, t2);
+   if (mpz_cmp(t1, modulus) >= 0) {
+      mpz_sub(t1, t1, modulus);
+   }
+   /* T1 = T1 + T2 */
+   mpz_add(t1, t1, t2);
+   if (mpz_cmp(t1, modulus) >= 0) {
+      mpz_sub(t1, t1, modulus);
+   }
+
+   /* Y = 2Y */
+   mpz_add(R->y, R->y, R->y);
+   if (mpz_cmp(R->y, modulus) >= 0) {
+      mpz_sub(R->y, R->y, modulus);
+   }
+   /* Y = Y * Y */
+   mpz_mul(R->y, R->y, R->y);
+   mpz_mod(R->y, R->y, modulus);
+   /* T2 = Y * Y */
+   mpz_mul(t2, R->y, R->y);
+   mpz_mod(t2, t2, modulus);
+   /* T2 = T2/2 */
+   if (mp_isodd(t2)) {
+      mpz_add(t2, t2, modulus);
+   }
+   mpz_divexact_ui(t2, t2, 2);
+   /* Y = Y * X */
+   mpz_mul(R->y, R->y, R->x);
+   mpz_mod(R->y, R->y, modulus);
+
+   /* X  = T1 * T1 */
+   mpz_mul(R->x, t1, t1);
+   mpz_mod(R->x, R->x, modulus);
+   /* X = X - Y */
+   mpz_sub(R->x, R->x, R->y);
+   if (mpz_cmp_ui(R->x, 0) < 0) {
+      mpz_add(R->x, R->x, modulus);
+   }
+   /* X = X - Y */
+   mpz_sub(R->x, R->x, R->y);
+   if (mpz_cmp_ui(R->x, 0) < 0) {
+      mpz_add(R->x, R->x, modulus);
+   }
+
+   /* Y = Y - X */     
+   mpz_sub(R->y, R->y, R->x);
+   if (mpz_cmp_ui(R->y, 0) < 0) {
+      mpz_add(R->y, R->y, modulus);
+   }
+   /* Y = Y * T1 */
+   mpz_mul(R->y, R->y, t1);
+   mpz_mod(R->y, R->y, modulus);
+   /* Y = Y - T2 */
+   mpz_sub(R->y, R->y, t2);
+   if (mpz_cmp_ui(R->y, 0) < 0) {
+      mpz_add( R->y, R->y, modulus);
+   }
+ 
+   err = 0;
+
+   mp_clear_multi(&t1, &t2, NULL);
+   return err;
+}
+#endif
+/* $Source: 
/cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c,v $ */
+/* $Revision: 1.11 $ */
+/* $Date: 2007/05/12 14:32:35 $ */
+
diff --git a/lib/nettle/ecc_shared_secret.c b/lib/nettle/ecc_shared_secret.c
index a7f5761..61012fd 100644
--- a/lib/nettle/ecc_shared_secret.c
+++ b/lib/nettle/ecc_shared_secret.c
@@ -9,7 +9,7 @@
  * Tom St Denis, address@hidden, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -22,8 +22,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
   Create an ECC shared secret between two keys
   @param private_key      The private ECC key
@@ -88,7 +86,6 @@ done:
   return err;
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_shared_secret.c,v $ */
 /* $Revision: 1.10 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
diff --git a/lib/nettle/ecc_sign_hash.c b/lib/nettle/ecc_sign_hash.c
index 09774cb..158949f 100644
--- a/lib/nettle/ecc_sign_hash.c
+++ b/lib/nettle/ecc_sign_hash.c
@@ -9,7 +9,7 @@
  * Tom St Denis, address@hidden, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -22,8 +22,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
   Sign a message digest
   @param in        The message digest to sign
@@ -111,7 +109,6 @@ errnokey:
   return err;
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_sign_hash.c,v $ */
 /* $Revision: 1.11 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
diff --git a/lib/nettle/ecc_test.c b/lib/nettle/ecc_test.c
index ff41b1d..0bdcd35 100644
--- a/lib/nettle/ecc_test.c
+++ b/lib/nettle/ecc_test.c
@@ -9,7 +9,7 @@
  * Tom St Denis, address@hidden, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -24,8 +24,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /**
   Perform on the ECC system
   @return 0 if successful
@@ -52,7 +50,7 @@ ecc_test (void)
       return -1;
     }
 
-  for (i = 1; i <= 2; i++)
+  for (i = 1; i <= 3; i++)
     {
       const gnutls_ecc_curve_entry_st *st = _gnutls_ecc_curve_get_params (i);
 
@@ -139,8 +137,6 @@ done:
   return err;
 }
 
-#endif
-
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_test.c,v $ */
 /* $Revision: 1.12 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
diff --git a/lib/nettle/ecc_verify_hash.c b/lib/nettle/ecc_verify_hash.c
index 7f62d64..b9f6ec0 100644
--- a/lib/nettle/ecc_verify_hash.c
+++ b/lib/nettle/ecc_verify_hash.c
@@ -9,7 +9,7 @@
  * Tom St Denis, address@hidden, http://libtom.org
  */
 
-/* Implements ECC over Z/pZ for curve y^2 = x^3 - ax + b
+/* Implements ECC over Z/pZ for curve y^2 = x^3 + ax + b
  *
  * All curves taken from NIST recommendation paper of July 1999
  * Available at http://csrc.nist.gov/cryptval/dss.htm
@@ -21,8 +21,6 @@
   ECC Crypto, Tom St Denis
 */
 
-#ifdef LTC_MECC
-
 /* verify 
  *
  * w  = s^-1 mod n
@@ -151,7 +149,6 @@ error:
   return err;
 }
 
-#endif
 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_verify_hash.c,v $ */
 /* $Revision: 1.14 $ */
 /* $Date: 2007/05/12 14:32:35 $ */
diff --git a/src/Makefile.am b/src/Makefile.am
index cc7881e..3cfbc08 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,7 +28,7 @@ AM_CPPFLAGS = \
        -I$(srcdir)/../libextra/includes        \
        -I$(srcdir)/cfg
 
-noinst_PROGRAMS = benchmark benchmark-tls
+noinst_PROGRAMS = benchmark-cipher benchmark-tls
 bin_PROGRAMS = gnutls-serv gnutls-cli psktool gnutls-cli-debug
 if ENABLE_PKI
 bin_PROGRAMS += certtool p11tool
@@ -65,10 +65,10 @@ noinst_LTLIBRARIES += libcmd-psk.la
 libcmd_psk_la_CFLAGS =
 libcmd_psk_la_SOURCES = psk.gaa psk-gaa.h psk-gaa.c
 
-benchmark_SOURCES = benchmark.c benchmark-common.c benchmark.h
-benchmark_LDADD = ../lib/libgnutls.la ../gl/libgnu.la $(LIB_CLOCK_GETTIME)
+benchmark_cipher_SOURCES = benchmark-cipher.c benchmark.c benchmark.h
+benchmark_cipher_LDADD = ../lib/libgnutls.la ../gl/libgnu.la 
$(LIB_CLOCK_GETTIME)
 
-benchmark_tls_SOURCES = benchmark-tls.c benchmark-common.c benchmark.h
+benchmark_tls_SOURCES = benchmark-tls.c benchmark.c benchmark.h
 benchmark_tls_LDADD = ../lib/libgnutls.la ../gl/libgnu.la $(LIB_CLOCK_GETTIME)
 
 gnutls_cli_SOURCES = cli.c common.h common.c p11common.c p11common.h
diff --git a/src/benchmark.c b/src/benchmark-cipher.c
similarity index 98%
copy from src/benchmark.c
copy to src/benchmark-cipher.c
index 0af831c..a69dd24 100644
--- a/src/benchmark.c
+++ b/src/benchmark-cipher.c
@@ -103,7 +103,7 @@ cipher_mac_bench (int algo, int mac_algo, int size)
   gnutls_cipher_deinit (ctx);
   gnutls_hmac_deinit(mac_ctx, NULL);
 
-  stop_benchmark (&st);
+  stop_benchmark (&st, NULL);
 
 leave:
   free (_key);
@@ -166,7 +166,7 @@ cipher_bench (int algo, int size, int aead)
 
   gnutls_cipher_deinit (ctx);
 
-  stop_benchmark(&st);
+  stop_benchmark(&st, NULL);
 
 leave:
   free (_key);
@@ -198,7 +198,7 @@ mac_bench (int algo, int size)
     }
   while (benchmark_must_finish == 0);
 
-  stop_benchmark(&st);
+  stop_benchmark(&st, NULL);
 
   free (_key);
 }
diff --git a/src/benchmark-common.c b/src/benchmark-common.c
deleted file mode 100644
index 0e47879..0000000
--- a/src/benchmark-common.c
+++ /dev/null
@@ -1,123 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <time.h>
-#include <unistd.h>
-#include "benchmark.h"
-
-int benchmark_must_finish = 0;
-
-#if defined(_WIN32)
-#include <windows.h>
-DWORD WINAPI
-alarm_handler (LPVOID lpParameter)
-{
-  HANDLE wtimer = *((HANDLE *) lpParameter);
-  WaitForSingleObject (wtimer, INFINITE);
-  benchmark_must_finish = 1;
-  return 0;
-}
-#else
-static void
-alarm_handler (int signo)
-{
-  benchmark_must_finish = 1;
-}
-#endif
-
-static void
-value2human (unsigned long bytes, double time, double *data, double *speed,
-             char *metric)
-{
-  if (bytes > 1000 && bytes < 1000 * 1000)
-    {
-      *data = ((double) bytes) / 1000;
-      *speed = *data / time;
-      strcpy (metric, "Kb");
-      return;
-    }
-  else if (bytes >= 1000 * 1000 && bytes < 1000 * 1000 * 1000)
-    {
-      *data = ((double) bytes) / (1000 * 1000);
-      *speed = *data / time;
-      strcpy (metric, "Mb");
-      return;
-    }
-  else if (bytes >= 1000 * 1000 * 1000)
-    {
-      *data = ((double) bytes) / (1000 * 1000 * 1000);
-      *speed = *data / time;
-      strcpy (metric, "Gb");
-      return;
-    }
-  else
-    {
-      *data = (double) bytes;
-      *speed = *data / time;
-      strcpy (metric, "bytes");
-      return;
-    }
-}
-
-void start_benchmark(struct benchmark_st * st)
-{
-  memset(st, 0, sizeof(st));
-  st->old_handler = signal (SIGALRM, alarm_handler);
-  gettime (&st->start);
-
-#if defined(_WIN32)
-  st->wtimer = CreateWaitableTimer (NULL, TRUE, NULL);
-  if (st->wtimer == NULL)
-    {
-      fprintf (stderr, "error: CreateWaitableTimer %u\n", GetLastError ());
-      exit(1);
-    }
-  st->wthread = CreateThread (NULL, 0, alarm_handler, &st->wtimer, 0, NULL);
-  if (st->wthread == NULL)
-    {
-      fprintf (stderr, "error: CreateThread %u\n", GetLastError ());
-      exit(1);
-    }
-  alarm_timeout.QuadPart = (5) * 10000000;
-  if (SetWaitableTimer (st->wtimer, &alarm_timeout, 0, NULL, NULL, FALSE) == 0)
-    {
-      fprintf (stderr, "error: SetWaitableTimer %u\n", GetLastError ());
-      exit(1);
-    }
-  }
-#else
-  alarm (5);
-#endif
-  
-}
-
-/* returns the elapsed time */
-double stop_benchmark(struct benchmark_st * st)
-{
-  double secs;
-  struct timespec stop;
-  double dspeed, ddata;
-  char metric[16];
-
-#if defined(_WIN32)
-  if (st->wtimer != NULL)
-    CloseHandle (st->wtimer);
-  if (st->wthread != NULL)
-    CloseHandle (st->wthread);
-#else
-  signal(SIGALRM, st->old_handler);
-#endif
-
-  gettime (&stop);
-
-  secs = (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) -
-          (st->start.tv_sec * 1000 + st->start.tv_nsec / (1000 * 1000)));
-  secs /= 1000;
-
-  value2human (st->size, secs, &ddata, &dspeed, metric);
-  printf ("Processed %.2f %s in %.2f secs: ", ddata, metric, secs);
-  printf ("%.2f %s/sec\n", dspeed, metric);
-
-  return secs;
-}
diff --git a/src/benchmark-tls.c b/src/benchmark-tls.c
index cc0c7a1..c8bd66d 100644
--- a/src/benchmark-tls.c
+++ b/src/benchmark-tls.c
@@ -40,6 +40,9 @@
 #include "../tests/eagain-common.h"
 #include "benchmark.h"
 
+#define PRIO_DH 
"NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+ANON-DH"
+#define PRIO_ECDH 
"NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+ANON-ECDH"
+
 #define PRIO_AES_CBC_SHA1 
"NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+ANON-DH"
 #define PRIO_CAMELLIA_CBC_SHA1 
"NONE:+VERS-TLS1.0:+CAMELLIA-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+ANON-DH"
 
@@ -150,7 +153,7 @@ test_ciphersuite (const char* cipher_prio, int size)
     }
   while (benchmark_must_finish == 0);
 
-  stop_benchmark (&st);
+  stop_benchmark (&st, NULL);
 
   gnutls_bye (client, GNUTLS_SHUT_WR);
   gnutls_bye (server, GNUTLS_SHUT_WR);
@@ -165,6 +168,85 @@ test_ciphersuite (const char* cipher_prio, int size)
 
 }
 
+static void
+test_ciphersuite_kx (const char* cipher_prio)
+{
+  /* Server stuff. */
+  gnutls_anon_server_credentials_t s_anoncred;
+  const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) };
+  static gnutls_dh_params_t dh_params;
+  gnutls_session_t server;
+  int sret, cret;
+  const char *str;
+  const char* suite=NULL;
+  /* Client stuff. */
+  gnutls_anon_client_credentials_t c_anoncred;
+  gnutls_session_t client;
+  /* Need to enable anonymous KX specifically. */
+  int ret;
+  struct benchmark_st st;
+
+  /* Init server */
+  gnutls_anon_allocate_server_credentials (&s_anoncred);
+  gnutls_dh_params_init (&dh_params);
+  gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM);
+  gnutls_anon_set_server_dh_params (s_anoncred, dh_params);
+
+  start_benchmark (&st);
+
+  do
+    {
+  gnutls_init (&server, GNUTLS_SERVER);
+  ret = gnutls_priority_set_direct (server, cipher_prio, &str);
+  if (ret < 0)
+    {
+      fprintf (stderr, "Error in %s\n", str);
+      exit (1);
+    }
+  gnutls_credentials_set (server, GNUTLS_CRD_ANON, s_anoncred);
+  gnutls_transport_set_push_function (server, server_push);
+  gnutls_transport_set_pull_function (server, server_pull);
+  gnutls_transport_set_ptr (server, (gnutls_transport_ptr_t) server);
+  reset_buffers();
+
+  /* Init client */
+  gnutls_anon_allocate_client_credentials (&c_anoncred);
+  gnutls_init (&client, GNUTLS_CLIENT);
+
+  ret = gnutls_priority_set_direct (client, cipher_prio, &str);
+  if (ret < 0)
+    {
+      fprintf (stderr, "Error in %s\n", str);
+      exit (1);
+    }
+  gnutls_credentials_set (client, GNUTLS_CRD_ANON, c_anoncred);
+  gnutls_transport_set_push_function (client, client_push);
+  gnutls_transport_set_pull_function (client, client_pull);
+  gnutls_transport_set_ptr (client, (gnutls_transport_ptr_t) client);
+
+  HANDSHAKE (client, server);
+
+  if (suite==NULL)
+    suite = gnutls_cipher_suite_get_name(gnutls_kx_get(server),
+               gnutls_cipher_get(server), gnutls_mac_get(server));
+
+  gnutls_deinit (client);
+  gnutls_deinit (server);
+
+      st.size += 1;
+    }
+  while (benchmark_must_finish == 0);
+
+  fprintf (stdout, "Tested %s: ", suite);
+  stop_benchmark (&st, "transactions");
+
+  gnutls_anon_free_client_credentials (c_anoncred);
+  gnutls_anon_free_server_credentials (s_anoncred);
+
+  gnutls_dh_params_deinit (dh_params);
+
+}
+
 int
 main (int argc, char **argv)
 {
@@ -175,6 +257,9 @@ main (int argc, char **argv)
     }
   gnutls_global_init ();
 
+  test_ciphersuite_kx (PRIO_DH);
+  test_ciphersuite_kx (PRIO_ECDH);
+
   test_ciphersuite (PRIO_AES_CBC_SHA1, 1024);
   test_ciphersuite (PRIO_AES_CBC_SHA1, 4096);
   test_ciphersuite (PRIO_AES_CBC_SHA1, 8*1024);
@@ -185,5 +270,6 @@ main (int argc, char **argv)
   test_ciphersuite (PRIO_CAMELLIA_CBC_SHA1, 8*1024);
   test_ciphersuite (PRIO_CAMELLIA_CBC_SHA1, 15*1024);
 
+
   gnutls_global_deinit ();
 }
diff --git a/src/benchmark.c b/src/benchmark.c
index 0af831c..befc81f 100644
--- a/src/benchmark.c
+++ b/src/benchmark.c
@@ -1,235 +1,134 @@
-/*
- * Copyright (C) 2009, 2010  Free Software Foundation, Inc.
- *
- * This file is part of GnuTLS.
- *
- * GnuTLS is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GnuTLS is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * Written by Nikos Mavrogiannopoulos <address@hidden>.
- */
-
-#include <config.h>
 #include <stdio.h>
 #include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <gnutls/gnutls.h>
-#include <gnutls/crypto.h>
-#include <time.h>
 #include <signal.h>
-#include "timespec.h"           /* gnulib gettime */
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
 #include "benchmark.h"
 
-static unsigned char data[64 * 1024];
-
+int benchmark_must_finish = 0;
 
+#if defined(_WIN32)
+#include <windows.h>
+DWORD WINAPI
+alarm_handler (LPVOID lpParameter)
+{
+  HANDLE wtimer = *((HANDLE *) lpParameter);
+  WaitForSingleObject (wtimer, INFINITE);
+  benchmark_must_finish = 1;
+  return 0;
+}
+#else
 static void
-tls_log_func (int level, const char *str)
+alarm_handler (int signo)
 {
-  fprintf (stderr, "|<%d>| %s", level, str);
+  benchmark_must_finish = 1;
 }
+#endif
 
 static void
-cipher_mac_bench (int algo, int mac_algo, int size)
+value2human (unsigned long bytes, double time, double *data, double *speed,
+             char *metric)
 {
-  int ret;
-  gnutls_cipher_hd_t ctx;
-  gnutls_hmac_hd_t mac_ctx;
-  void *_key, *_iv;
-  gnutls_datum_t key, iv;
-  int blocksize = gnutls_cipher_get_block_size (algo);
-  int keysize = gnutls_cipher_get_key_size (algo);
-  int step = size*1024;
-  struct benchmark_st st;
-
-  _key = malloc (keysize);
-  if (_key == NULL)
-    return;
-  memset (_key, 0xf0, keysize);
-
-  _iv = malloc (blocksize);
-  if (_iv == NULL)
-    return;
-  memset (_iv, 0xf0, blocksize);
-
-  iv.data = _iv;
-  iv.size = blocksize;
-
-  key.data = _key;
-  key.size = keysize;
-
-  printf ("Checking %s with %s (%dkb payload)... ", gnutls_cipher_get_name 
(algo),
-      gnutls_mac_get_name(mac_algo), size);
-  fflush (stdout);
-
-  start_benchmark(&st);
-
-  ret = gnutls_hmac_init(&mac_ctx, mac_algo, key.data, key.size);
-  if (ret < 0)
+  if (bytes > 1000 && bytes < 1000 * 1000)
     {
-      fprintf (stderr, "error: %s\n", gnutls_strerror (ret));
-      goto leave;
+      *data = ((double) bytes) / 1000;
+      *speed = *data / time;
+      strcpy (metric, "Kb");
+      return;
     }
-
-  ret = gnutls_cipher_init (&ctx, algo, &key, &iv);
-  if (ret < 0)
+  else if (bytes >= 1000 * 1000 && bytes < 1000 * 1000 * 1000)
     {
-      fprintf (stderr, "error: %s\n", gnutls_strerror (ret));
-      goto leave;
+      *data = ((double) bytes) / (1000 * 1000);
+      *speed = *data / time;
+      strcpy (metric, "Mb");
+      return;
     }
-
-  gnutls_hmac(mac_ctx, data, 1024);
-
-  do
+  else if (bytes >= 1000 * 1000 * 1000)
     {
-      gnutls_hmac(mac_ctx, data, step);
-      gnutls_cipher_encrypt (ctx, data, step);
-      st.size += step;
+      *data = ((double) bytes) / (1000 * 1000 * 1000);
+      *speed = *data / time;
+      strcpy (metric, "Gb");
+      return;
+    }
+  else
+    {
+      *data = (double) bytes;
+      *speed = *data / time;
+      strcpy (metric, "bytes");
+      return;
     }
-  while (benchmark_must_finish == 0);
-
-  gnutls_cipher_deinit (ctx);
-  gnutls_hmac_deinit(mac_ctx, NULL);
-
-  stop_benchmark (&st);
-
-leave:
-  free (_key);
-  free (_iv);
-
 }
 
-
-static void
-cipher_bench (int algo, int size, int aead)
+void start_benchmark(struct benchmark_st * st)
 {
-  int ret;
-  gnutls_cipher_hd_t ctx;
-  void *_key, *_iv;
-  gnutls_datum_t key, iv;
-  int blocksize = gnutls_cipher_get_block_size (algo);
-  int keysize = gnutls_cipher_get_key_size (algo);
-  int step = size*1024;
-  struct benchmark_st st;
-
-  _key = malloc (keysize);
-  if (_key == NULL)
-    return;
-  memset (_key, 0xf0, keysize);
-
-  _iv = malloc (blocksize);
-  if (_iv == NULL)
-    return;
-  memset (_iv, 0xf0, blocksize);
-
-  iv.data = _iv;
-  if (aead) iv.size = 12;
-  else iv.size = blocksize;
-
-  key.data = _key;
-  key.size = keysize;
-
-  printf ("Checking %s (%dkb payload)... ", gnutls_cipher_get_name (algo),
-          size);
-  fflush (stdout);
-
-  start_benchmark(&st);
-
-  ret = gnutls_cipher_init (&ctx, algo, &key, &iv);
-  if (ret < 0)
+  memset(st, 0, sizeof(st));
+  st->old_handler = signal (SIGALRM, alarm_handler);
+  gettime (&st->start);
+  benchmark_must_finish = 0;
+
+#if defined(_WIN32)
+  st->wtimer = CreateWaitableTimer (NULL, TRUE, NULL);
+  if (st->wtimer == NULL)
     {
-      fprintf (stderr, "error: %s\n", gnutls_strerror (ret));
-      goto leave;
+      fprintf (stderr, "error: CreateWaitableTimer %u\n", GetLastError ());
+      exit(1);
     }
-
-  if (aead)
-    gnutls_cipher_add_auth (ctx, data, 1024);
-
-  do
+  st->wthread = CreateThread (NULL, 0, alarm_handler, &st->wtimer, 0, NULL);
+  if (st->wthread == NULL)
     {
-      gnutls_cipher_encrypt (ctx, data, step);
-      st.size += step;
+      fprintf (stderr, "error: CreateThread %u\n", GetLastError ());
+      exit(1);
     }
-  while (benchmark_must_finish == 0);
-
-  gnutls_cipher_deinit (ctx);
-
-  stop_benchmark(&st);
-
-leave:
-  free (_key);
-  free (_iv);
-}
-
-static void
-mac_bench (int algo, int size)
-{
-  void *_key;
-  int blocksize = gnutls_hmac_get_len (algo);
-  int step = size*1024;
-  struct benchmark_st st;
-  
-  _key = malloc (blocksize);
-  if (_key == NULL)
-    return;
-  memset (_key, 0xf0, blocksize);
-
-  printf ("Checking %s (%dkb payload)... ", gnutls_mac_get_name (algo), size);
-  fflush (stdout);
-
-  start_benchmark(&st);
-
-  do
+  alarm_timeout.QuadPart = (5) * 10000000;
+  if (SetWaitableTimer (st->wtimer, &alarm_timeout, 0, NULL, NULL, FALSE) == 0)
     {
-      gnutls_hmac_fast (algo, _key, blocksize, data, step, _key);
-      st.size += step;
+      fprintf (stderr, "error: SetWaitableTimer %u\n", GetLastError ());
+      exit(1);
     }
-  while (benchmark_must_finish == 0);
-
-  stop_benchmark(&st);
-
-  free (_key);
+  }
+#else
+  alarm (5);
+#endif
+  
 }
 
-int
-main (int argc, char **argv)
+/* returns the elapsed time */
+double stop_benchmark(struct benchmark_st * st, const char* metric)
 {
-  int debug_level = 0;
-
-  if (argc > 1)
-    debug_level = 2;
-
-  gnutls_global_set_log_function (tls_log_func);
-  gnutls_global_set_log_level (debug_level);
-  gnutls_global_init ();
-
-  gnutls_rnd( GNUTLS_RND_NONCE, data, sizeof(data));
-
-  cipher_bench ( GNUTLS_CIPHER_AES_128_GCM, 16, 1);
-  cipher_mac_bench ( GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA256, 16);
-  cipher_mac_bench ( GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1, 16);
-
-  mac_bench (GNUTLS_MAC_SHA1, 16);
-
-  mac_bench (GNUTLS_MAC_SHA256, 16);
-
-  cipher_bench (GNUTLS_CIPHER_3DES_CBC, 16, 0);
-
-  cipher_bench (GNUTLS_CIPHER_AES_128_CBC, 16, 0);
-
-  cipher_bench (GNUTLS_CIPHER_ARCFOUR, 16, 0);
+  double secs;
+  struct timespec stop;
+  double dspeed, ddata;
+  char imetric[16];
+
+#if defined(_WIN32)
+  if (st->wtimer != NULL)
+    CloseHandle (st->wtimer);
+  if (st->wthread != NULL)
+    CloseHandle (st->wthread);
+#else
+  signal(SIGALRM, st->old_handler);
+#endif
+
+  gettime (&stop);
+
+  secs = (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) -
+          (st->start.tv_sec * 1000 + st->start.tv_nsec / (1000 * 1000)));
+  secs /= 1000;
+
+  if (metric == NULL)
+    { /* assume bytes/sec */
+      value2human (st->size, secs, &ddata, &dspeed, imetric);
+      printf ("Processed %.2f %s in %.2f secs: ", ddata, imetric, secs);
+      printf ("%.2f %s/sec\n", dspeed, imetric);
+    }
+  else
+    {
+      ddata = (double) st->size;
+      dspeed = ddata / secs;
+      printf ("Processed %.2f %s in %.2f secs: ", ddata, metric, secs);
+      printf ("%.2f %s/sec\n", dspeed, metric);
+    }
 
-  return 0;
+  return secs;
 }
diff --git a/src/benchmark.h b/src/benchmark.h
index 826ed20..b5a7f86 100644
--- a/src/benchmark.h
+++ b/src/benchmark.h
@@ -20,5 +20,5 @@ struct benchmark_st
 extern int benchmark_must_finish;
 
 void start_benchmark(struct benchmark_st * st);
-double stop_benchmark(struct benchmark_st * st);
+double stop_benchmark(struct benchmark_st * st, const char* metric);
 
diff --git a/tests/eagain-common.h b/tests/eagain-common.h
index dbc5f33..c55e97c 100644
--- a/tests/eagain-common.h
+++ b/tests/eagain-common.h
@@ -229,7 +229,7 @@ int ret;
   return ret;
 }
 
-static void reset_buffers(void)
+inline static void reset_buffers(void)
 {
   to_server_len = 0;
   to_client_len = 0;


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]