Merged IPv6 support in the NET module
diff --git a/ChangeLog b/ChangeLog
index 84115d4..3eadbcc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,8 @@
    * Support for adhering to client ciphersuite order preference
      (POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
    * Support for Curve25519
+   * Support for ECDH-RSA and ECDH-ECDSA key exchanges and ciphersuites
+   * Support for IPv6 in the NET module
 
 Changes
    * gen_prime() speedup
@@ -14,6 +16,7 @@
    * Dropped use of readdir_r() instead of readdir() with threading support
    * More constant-time checks in the RSA module
    * Split off curves from ecp.c into ecp_curves.c
+   * Curves are now stored fully in ROM
 
 Bugfix
    * Fixed bug in mpi_set_bit() on platforms where t_uint is wider than int
@@ -21,6 +24,8 @@
    * SSL now gracefully handles missing RNG
    * Missing defines / cases for RSA_PSK key exchange
    * crypt_and_hash app checks MAC before final decryption
+   * Potential memory leak in ssl_ticket_keys_init()
+   * Memory leak in benchmark application
 
 = PolarSSL 1.3.2 released on 2013-11-04
 Features
diff --git a/include/polarssl/bignum.h b/include/polarssl/bignum.h
index df17b12..681a1de 100644
--- a/include/polarssl/bignum.h
+++ b/include/polarssl/bignum.h
@@ -127,12 +127,18 @@
 typedef uint32_t t_udbl;
 #define POLARSSL_HAVE_UDBL
 #else
-  #if ( defined(_MSC_VER) && defined(_M_AMD64) )
+  /*
+   * 32-bit integers can be forced on 64-bit arches (eg. for testing purposes)
+   * by defining POLARSSL_HAVE_INT32 and undefining POARSSL_HAVE_ASM
+   */
+  #if ( ! defined(POLARSSL_HAVE_INT32) && \
+          defined(_MSC_VER) && defined(_M_AMD64) )
     #define POLARSSL_HAVE_INT64
     typedef  int64_t t_sint;
     typedef uint64_t t_uint;
   #else
-    #if ( defined(__GNUC__) && (                          \
+    #if ( ! defined(POLARSSL_HAVE_INT32) &&               \
+          defined(__GNUC__) && (                          \
           defined(__amd64__) || defined(__x86_64__)    || \
           defined(__ppc64__) || defined(__powerpc64__) || \
           defined(__ia64__)  || defined(__alpha__)     || \
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index 0a64092..7bbef55 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -190,6 +190,8 @@
  *
  * Requires POLARSSL_ENABLE_WEAK_CIPHERSUITES as well to enable
  * the following ciphersuites:
+ *      TLS_ECDH_ECDSA_WITH_NULL_SHA
+ *      TLS_ECDH_RSA_WITH_NULL_SHA
  *      TLS_ECDHE_ECDSA_WITH_NULL_SHA
  *      TLS_ECDHE_RSA_WITH_NULL_SHA
  *      TLS_ECDHE_PSK_WITH_NULL_SHA384
@@ -469,6 +471,54 @@
 #define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 
 /**
+ * \def POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+ *
+ * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ *      TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ *      TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ *      TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ *      TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ *      TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ *      TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ *      TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+
+/**
+ * \def POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED
+ *
+ * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      TLS_ECDH_RSA_WITH_RC4_128_SHA
+ *      TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ *      TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ *      TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ *      TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ *      TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ *      TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ *      TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ *      TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+#define POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED
+
+/**
  * \def POLARSSL_ERROR_STRERROR_BC
  *
  * Make available the backward compatible error_strerror() next to the
@@ -834,6 +884,18 @@
  *
  * This module enables the following ciphersuites (if other requisites are
  * enabled as well):
+ *      TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ *      TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ *      TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ *      TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ *      TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ *      TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ *      TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ *      TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ *      TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ *      TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ *      TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ *      TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
  *      TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  *      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  *      TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
@@ -895,6 +957,8 @@
  *
  * This module enables the following ciphersuites (if other requisites are
  * enabled as well):
+ *      TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ *      TLS_ECDH_RSA_WITH_RC4_128_SHA
  *      TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
  *      TLS_ECDHE_RSA_WITH_RC4_128_SHA
  *      TLS_ECDHE_PSK_WITH_RC4_128_SHA
@@ -980,6 +1044,14 @@
  *
  * This module enables the following ciphersuites (if other requisites are
  * enabled as well):
+ *      TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
  *      TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
  *      TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
  *      TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
@@ -1082,6 +1154,8 @@
  *
  * This module enables the following ciphersuites (if other requisites are
  * enabled as well):
+ *      TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
  *      TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
  *      TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
  *      TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
@@ -1883,6 +1957,16 @@
 #error "POLARSSL_HAVEGE_C defined, but not all prerequisites"
 #endif
 
+#if defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) &&                 \
+    ( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_X509_CRT_PARSE_C) )
+#error "POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) &&                 \
+    ( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_X509_CRT_PARSE_C) )
+#error "POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
+#endif
+
 #if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(POLARSSL_DHM_C)
 #error "POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites"
 #endif
diff --git a/include/polarssl/ecdh.h b/include/polarssl/ecdh.h
index 4c82f25..d20f9bf 100644
--- a/include/polarssl/ecdh.h
+++ b/include/polarssl/ecdh.h
@@ -34,6 +34,15 @@
 #endif
 
 /**
+ * When importing from an EC key, select if it is our key or the peer's key
+ */
+typedef enum
+{
+    POLARSSL_ECDH_OURS,
+    POLARSSL_ECDH_THEIRS,
+} ecdh_side;
+
+/**
  * \brief           ECDH context structure
  */
 typedef struct
@@ -135,6 +144,18 @@
                       const unsigned char **buf, const unsigned char *end );
 
 /**
+ * \brief           Setup an ECDH context from an EC key
+ *
+ * \param ctx       ECDH constext to set
+ * \param key       EC key to use
+ * \param ours      Is it our key (1) or the peer's key (0) ?
+ *
+ * \return          0 if successful, or an POLARSSL_ERR_ECP_XXX error code
+ */
+int ecdh_get_params( ecdh_context *ctx, const ecp_keypair *key,
+                     ecdh_side side );
+
+/**
  * \brief           Setup and export the client's public value
  *
  * \param ctx       ECDH context
diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h
index 2ab458a..ff1072e 100644
--- a/include/polarssl/ecp.h
+++ b/include/polarssl/ecp.h
@@ -136,7 +136,7 @@
     mpi N;              /*!<  1. the order of G, or 2. unused               */
     size_t pbits;       /*!<  number of bits in P                           */
     size_t nbits;       /*!<  number of bits in 1. P, or 2. private keys    */
-    unsigned int h;     /*!<  unused                                        */
+    unsigned int h;     /*!<  internal: 1 if the constants are static       */
     int (*modp)(mpi *); /*!<  function for fast reduction mod P             */
     int (*t_pre)(ecp_point *, void *);  /*!< unused                         */
     int (*t_post)(ecp_point *, void *); /*!< unused                         */
diff --git a/include/polarssl/ssl_ciphersuites.h b/include/polarssl/ssl_ciphersuites.h
index 7e91617..3b13ef3 100644
--- a/include/polarssl/ssl_ciphersuites.h
+++ b/include/polarssl/ssl_ciphersuites.h
@@ -120,12 +120,24 @@
 #define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256     0xC0   /**< TLS 1.2 */
 #define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC4   /**< TLS 1.2 */
 
+#define TLS_ECDH_ECDSA_WITH_NULL_SHA             0xC001 /**< Weak! */
+#define TLS_ECDH_ECDSA_WITH_RC4_128_SHA          0xC002 /**< Not in SSL3! */
+#define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA     0xC003 /**< Not in SSL3! */
+#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA      0xC004 /**< Not in SSL3! */
+#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA      0xC005 /**< Not in SSL3! */
+
 #define TLS_ECDHE_ECDSA_WITH_NULL_SHA            0xC006 /**< Weak! */
 #define TLS_ECDHE_ECDSA_WITH_RC4_128_SHA         0xC007 /**< Not in SSL3! */
 #define TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA    0xC008 /**< Not in SSL3! */
 #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA     0xC009 /**< Not in SSL3! */
 #define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA     0xC00A /**< Not in SSL3! */
 
+#define TLS_ECDH_RSA_WITH_NULL_SHA               0xC00B /**< Weak! */
+#define TLS_ECDH_RSA_WITH_RC4_128_SHA            0xC00C /**< Not in SSL3! */
+#define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA       0xC00D /**< Not in SSL3! */
+#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA        0xC00E /**< Not in SSL3! */
+#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA        0xC00F /**< Not in SSL3! */
+
 #define TLS_ECDHE_RSA_WITH_NULL_SHA              0xC010 /**< Weak! */
 #define TLS_ECDHE_RSA_WITH_RC4_128_SHA           0xC011 /**< Not in SSL3! */
 #define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA      0xC012 /**< Not in SSL3! */
@@ -134,15 +146,21 @@
 
 #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256  0xC023 /**< TLS 1.2 */
 #define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384  0xC024 /**< TLS 1.2 */
-
+#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256   0xC025 /**< TLS 1.2 */
+#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384   0xC026 /**< TLS 1.2 */
 #define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256    0xC027 /**< TLS 1.2 */
 #define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384    0xC028 /**< TLS 1.2 */
+#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256     0xC029 /**< TLS 1.2 */
+#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384     0xC02A /**< TLS 1.2 */
 
 #define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256  0xC02B /**< TLS 1.2 */
 #define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384  0xC02C /**< TLS 1.2 */
-
+#define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256   0xC02D /**< TLS 1.2 */
+#define TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384   0xC02E /**< TLS 1.2 */
 #define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256    0xC02F /**< TLS 1.2 */
 #define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384    0xC030 /**< TLS 1.2 */
+#define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256     0xC031 /**< TLS 1.2 */
+#define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384     0xC032 /**< TLS 1.2 */
 
 #define TLS_ECDHE_PSK_WITH_RC4_128_SHA           0xC033 /**< Not in SSL3! */
 #define TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA      0xC034 /**< Not in SSL3! */
@@ -156,8 +174,12 @@
 
 #define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 /**< Not in SSL3! */
 #define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 /**< Not in SSL3! */
+#define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256  0xC074 /**< Not in SSL3! */
+#define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384  0xC075 /**< Not in SSL3! */
 #define TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256   0xC076 /**< Not in SSL3! */
 #define TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384   0xC077 /**< Not in SSL3! */
+#define TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256    0xC078 /**< Not in SSL3! */
+#define TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384    0xC079 /**< Not in SSL3! */
 
 #define TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256         0xC07A /**< TLS 1.2 */
 #define TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384         0xC07B /**< TLS 1.2 */
@@ -165,10 +187,14 @@
 #define TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384     0xC07D /**< TLS 1.2 */
 #define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC086 /**< TLS 1.2 */
 #define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC087 /**< TLS 1.2 */
+#define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256  0xC088 /**< TLS 1.2 */
+#define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384  0xC089 /**< TLS 1.2 */
 #define TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256   0xC08A /**< TLS 1.2 */
 #define TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384   0xC08B /**< TLS 1.2 */
+#define TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256    0xC08C /**< TLS 1.2 */
+#define TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384    0xC08D /**< TLS 1.2 */
 
-#define TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256       0xC08D /**< TLS 1.2 */
+#define TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256       0xC08E /**< TLS 1.2 */
 #define TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384       0xC08F /**< TLS 1.2 */
 #define TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256   0xC090 /**< TLS 1.2 */
 #define TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384   0xC091 /**< TLS 1.2 */
@@ -194,6 +220,8 @@
     POLARSSL_KEY_EXCHANGE_DHE_PSK,
     POLARSSL_KEY_EXCHANGE_RSA_PSK,
     POLARSSL_KEY_EXCHANGE_ECDHE_PSK,
+    POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+    POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
 } key_exchange_type_t;
 
 typedef struct _ssl_ciphersuite_t ssl_ciphersuite_t;
diff --git a/library/cipher.c b/library/cipher.c
index f0a770a..bfb229e 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -241,13 +241,13 @@
 {
     int ret;
 
-    *olen = 0;
-
     if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
     {
         return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
     }
 
+    *olen = 0;
+
     if( ctx->cipher_info->mode == POLARSSL_MODE_ECB )
     {
         if( ilen != cipher_get_block_size( ctx ) )
diff --git a/library/ecdh.c b/library/ecdh.c
index 400e45f..302531d 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -166,6 +166,32 @@
 }
 
 /*
+ * Get parameters from a keypair
+ */
+int ecdh_get_params( ecdh_context *ctx, const ecp_keypair *key,
+                     ecdh_side side )
+{
+    int ret;
+
+    if( ( ret = ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 )
+        return( ret );
+
+    /* If it's not our key, just import the public part as Qp */
+    if( side == POLARSSL_ECDH_THEIRS )
+        return( ecp_copy( &ctx->Qp, &key->Q ) );
+
+    /* Our key: import public (as Q) and private parts */
+    if( side != POLARSSL_ECDH_OURS )
+        return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
+
+    if( ( ret = ecp_copy( &ctx->Q, &key->Q ) ) != 0 ||
+        ( ret = mpi_copy( &ctx->d, &key->d ) ) != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+/*
  * Setup and export the client public value
  */
 int ecdh_make_public( ecdh_context *ctx, size_t *olen,
diff --git a/library/ecp.c b/library/ecp.c
index 02f1b61..8c5c06e 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -280,11 +280,14 @@
     if( grp == NULL )
         return;
 
-    mpi_free( &grp->P );
-    mpi_free( &grp->A );
-    mpi_free( &grp->B );
-    ecp_point_free( &grp->G );
-    mpi_free( &grp->N );
+    if( grp->h != 1 )
+    {
+        mpi_free( &grp->P );
+        mpi_free( &grp->A );
+        mpi_free( &grp->B );
+        ecp_point_free( &grp->G );
+        mpi_free( &grp->N );
+    }
 
     if( grp->T != NULL )
     {
@@ -523,7 +526,6 @@
     int ret;
 
     MPI_CHK( mpi_read_string( &grp->P, radix, p ) );
-    MPI_CHK( mpi_add_int( &grp->A, &grp->P, -3 ) );
     MPI_CHK( mpi_read_string( &grp->B, radix, b ) );
     MPI_CHK( ecp_point_read_string( &grp->G, radix, gx, gy ) );
     MPI_CHK( mpi_read_string( &grp->N, radix, n ) );
@@ -864,7 +866,17 @@
     MPI_CHK( mpi_mul_mpi( &Z3,  &P->Z,  &P->Z   ) ); MOD_MUL( Z3 );
     MPI_CHK( mpi_mul_mpi( &X3,  &Z3,    &Z3     ) ); MOD_MUL( X3 );
     MPI_CHK( mpi_mul_int( &T3,  &T3,    3       ) ); MOD_ADD( T3 );
-    MPI_CHK( mpi_mul_mpi( &X3,  &X3,    &grp->A ) ); MOD_MUL( X3 );
+
+    /* Special case for A = -3 */
+    if( grp->A.p == NULL )
+    {
+        MPI_CHK( mpi_mul_int( &X3, &X3, 3 ) );
+        X3.s = -1; /* mpi_mul_int doesn't handle negative numbers */
+        MOD_SUB( X3 );
+    }
+    else
+        MPI_CHK( mpi_mul_mpi( &X3,  &X3,    &grp->A ) ); MOD_MUL( X3 );
+
     MPI_CHK( mpi_add_mpi( &T3,  &T3,    &X3     ) ); MOD_ADD( T3 );
     MPI_CHK( mpi_mul_mpi( &X3,  &T3,    &T3     ) ); MOD_MUL( X3 );
     MPI_CHK( mpi_sub_mpi( &X3,  &X3,    &T1     ) ); MOD_SUB( X3 );
@@ -1629,7 +1641,17 @@
      */
     MPI_CHK( mpi_mul_mpi( &YY,  &pt->Y,   &pt->Y  ) );  MOD_MUL( YY  );
     MPI_CHK( mpi_mul_mpi( &RHS, &pt->X,   &pt->X  ) );  MOD_MUL( RHS );
-    MPI_CHK( mpi_add_mpi( &RHS, &RHS,     &grp->A ) );  MOD_ADD( RHS );
+
+    /* Special case for A = -3 */
+    if( grp->A.p == NULL )
+    {
+        MPI_CHK( mpi_sub_int( &RHS, &RHS, 3       ) );  MOD_SUB( RHS );
+    }
+    else
+    {
+        MPI_CHK( mpi_add_mpi( &RHS, &RHS, &grp->A ) );  MOD_ADD( RHS );
+    }
+
     MPI_CHK( mpi_mul_mpi( &RHS, &RHS,     &pt->X  ) );  MOD_MUL( RHS );
     MPI_CHK( mpi_add_mpi( &RHS, &RHS,     &grp->B ) );  MOD_ADD( RHS );
 
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index 26d9e1e..d3b518a 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -38,286 +38,497 @@
 #endif /*_MSC_VER */
 
 /*
+ * Conversion macros for embedded constants:
+ * build lists of t_uint's from lists of unsigned char's grouped by 8, 4 or 2
+ */
+#if defined(POLARSSL_HAVE_INT8)
+
+#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
+    a, b, c, d, e, f, g, h
+
+#define BYTES_TO_T_UINT_4( a, b, c, d )             \
+    a, b, c, d
+
+#define BYTES_TO_T_UINT_2( a, b )                   \
+    a, b
+
+#elif defined(POLARSSL_HAVE_INT16)
+
+#define BYTES_TO_T_UINT_2( a, b )                   \
+    ( (t_uint) a << 0 ) |                           \
+    ( (t_uint) b << 8 )
+
+#define BYTES_TO_T_UINT_4( a, b, c, d )             \
+    BYTES_TO_T_UINT_2( a, b ),                      \
+    BYTES_TO_T_UINT_2( c, d )
+
+#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
+    BYTES_TO_T_UINT_2( a, b ),                      \
+    BYTES_TO_T_UINT_2( c, d ),                      \
+    BYTES_TO_T_UINT_2( e, f ),                      \
+    BYTES_TO_T_UINT_2( g, h )
+
+#elif defined(POLARSSL_HAVE_INT32)
+
+#define BYTES_TO_T_UINT_4( a, b, c, d )             \
+    ( (t_uint) a <<  0 ) |                          \
+    ( (t_uint) b <<  8 ) |                          \
+    ( (t_uint) c << 16 ) |                          \
+    ( (t_uint) d << 24 )
+
+#define BYTES_TO_T_UINT_2( a, b )                   \
+    BYTES_TO_T_UINT_4( a, b, 0, 0 )
+
+#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
+    BYTES_TO_T_UINT_4( a, b, c, d ),                \
+    BYTES_TO_T_UINT_4( e, f, g, h )
+
+#else /* 64-bits */
+
+#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
+    ( (t_uint) a <<  0 ) |                          \
+    ( (t_uint) b <<  8 ) |                          \
+    ( (t_uint) c << 16 ) |                          \
+    ( (t_uint) d << 24 ) |                          \
+    ( (t_uint) e << 32 ) |                          \
+    ( (t_uint) f << 40 ) |                          \
+    ( (t_uint) g << 48 ) |                          \
+    ( (t_uint) h << 56 )
+
+#define BYTES_TO_T_UINT_4( a, b, c, d )             \
+    BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 )
+
+#define BYTES_TO_T_UINT_2( a, b )                   \
+    BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 )
+
+#endif /* bits in t_uint */
+
+/*
+ * Note: the constants are in little-endian order
+ * to be directly usable in MPIs
+ */
+
+/*
  * Domain parameters for secp192r1
  */
-static unsigned char secp192r1_p[] = {
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-static unsigned char *secp192r1_a = NULL;
-static unsigned char secp192r1_b[] = {
-    0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7, 0xE9, 0xAB,
-    0x72, 0x24, 0x30, 0x49, 0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1 };
-static unsigned char secp192r1_gx[] = {
-    0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF, 0x20, 0xEB,
-    0x43, 0xA1, 0x88, 0x00, 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12 };
-static unsigned char secp192r1_gy[] = {
-    0x07, 0x19, 0x2B, 0x95, 0xFF, 0xC8, 0xDA, 0x78, 0x63, 0x10, 0x11, 0xED,
-    0x6B, 0x24, 0xCD, 0xD5, 0x73, 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11 };
-static unsigned char secp192r1_n[] = {
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0x99, 0xDE, 0xF8, 0x36, 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31 };
+#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
+static t_uint secp192r1_p[] = {
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static t_uint secp192r1_b[] = {
+    BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
+    BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
+    BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
+};
+static t_uint secp192r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
+    BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
+    BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
+};
+static t_uint secp192r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
+    BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
+    BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
+};
+static t_uint secp192r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
+    BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */
 
 /*
  * Domain parameters for secp224r1
  */
-static unsigned char secp224r1_p[] = {
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x01 };
-static unsigned char *secp224r1_a = NULL;
-static unsigned char secp224r1_b[] = {
-    0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
-    0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
-    0x23, 0x55, 0xFF, 0xB4 };
-static unsigned char secp224r1_gx[] = {
-    0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
-    0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
-    0x11, 0x5C, 0x1D, 0x21 };
-static unsigned char secp224r1_gy[] = {
-    0xBD, 0x37, 0x63, 0x88, 0xB5, 0xF7, 0x23, 0xFB, 0x4C, 0x22, 0xDF, 0xE6,
-    0xCD, 0x43, 0x75, 0xA0, 0x5A, 0x07, 0x47, 0x64, 0x44, 0xD5, 0x81, 0x99,
-    0x85, 0x00, 0x7E, 0x34 };
-static unsigned char secp224r1_n[] = {
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
-    0x5C, 0x5C, 0x2A, 0x3D };
+#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
+static t_uint secp224r1_p[] = {
+    BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
+};
+static t_uint secp224r1_b[] = {
+    BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
+    BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
+    BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
+    BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
+};
+static t_uint secp224r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
+    BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
+    BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
+    BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
+};
+static t_uint secp224r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
+    BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
+    BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
+    BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
+};
+static t_uint secp224r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
+    BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */
 
 /*
  * Domain parameters for secp256r1
  */
-static unsigned char secp256r1_p[] = {
-    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-static unsigned char *secp256r1_a = NULL;
-static unsigned char secp256r1_b[] = {
-    0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
-    0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
-    0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B };
-static unsigned char secp256r1_gx[] = {
-    0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
-    0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
-    0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96 };
-static unsigned char secp256r1_gy[] = {
-    0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A,
-    0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE,
-    0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 };
-static unsigned char secp256r1_n[] = {
-    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
-    0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 };
+#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
+static t_uint secp256r1_p[] = {
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
+    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+    BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static t_uint secp256r1_b[] = {
+    BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
+    BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
+    BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
+    BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
+};
+static t_uint secp256r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
+    BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
+    BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
+    BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
+};
+static t_uint secp256r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
+    BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
+    BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
+    BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
+};
+static t_uint secp256r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
+    BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */
 
 /*
  * Domain parameters for secp384r1
  */
-static unsigned char secp384r1_p[] = {
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF };
-static unsigned char *secp384r1_a = NULL;
-static unsigned char secp384r1_b[] = {
-    0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
-    0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
-    0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
-    0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF };
-static unsigned char secp384r1_gx[] = {
-    0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
-    0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
-    0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
-    0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7 };
-static unsigned char secp384r1_gy[] = {
-    0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF,
-    0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C,
-    0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE,
-    0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F };
-static unsigned char secp384r1_n[] = {
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
-    0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 };
+#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
+static t_uint secp384r1_p[] = {
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
+    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static t_uint secp384r1_b[] = {
+    BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
+    BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
+    BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
+    BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
+    BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
+    BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
+};
+static t_uint secp384r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
+    BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
+    BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
+    BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
+    BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
+    BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
+};
+static t_uint secp384r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
+    BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
+    BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
+    BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
+    BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
+    BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
+};
+static t_uint secp384r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
+    BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
+    BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */
 
 /*
  * Domain parameters for secp521r1
  */
-static unsigned char secp521r1_p[] = {
-    0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-static unsigned char *secp521r1_a = NULL;
-static unsigned char secp521r1_b[] = {
-    0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
-    0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
-    0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
-    0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
-    0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
-    0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00 };
-static unsigned char secp521r1_gx[] = {
-    0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
-    0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
-    0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
-    0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
-    0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
-    0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66 };
-static unsigned char secp521r1_gy[] = {
-    0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A,
-    0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B,
-    0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE,
-    0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD,
-    0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE,
-    0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50 };
-static unsigned char secp521r1_n[] = {
-    0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
-    0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
-    0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
-    0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09 };
+#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
+static t_uint secp521r1_p[] = {
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
+};
+static t_uint secp521r1_b[] = {
+    BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
+    BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
+    BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
+    BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
+    BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
+    BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
+    BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
+    BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
+    BYTES_TO_T_UINT_2( 0x51, 0x00 ),
+};
+static t_uint secp521r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
+    BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
+    BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
+    BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
+    BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
+    BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
+    BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
+    BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
+    BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
+};
+static t_uint secp521r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
+    BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
+    BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
+    BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
+    BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
+    BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
+    BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
+    BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
+    BYTES_TO_T_UINT_2( 0x18, 0x01 ),
+};
+static t_uint secp521r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
+    BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
+    BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
+    BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
+    BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
+};
+#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */
 
 /*
  * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
  */
-static unsigned char brainpoolP256r1_p[] = {
-    0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90,
-    0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28,
-    0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77 };
-static unsigned char brainpoolP256r1_a[] = {
-    0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57, 0xEE, 0xF6, 0x75, 0x30,
-    0x41, 0x7A, 0xFF, 0xE7, 0xFB, 0x80, 0x55, 0xC1, 0x26, 0xDC, 0x5C, 0x6C,
-    0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9 };
-static unsigned char brainpoolP256r1_b[] = {
-    0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9,
-    0xBB, 0xD7, 0x7C, 0xBF, 0x95, 0x84, 0x16, 0x29, 0x5C, 0xF7, 0xE1, 0xCE,
-    0x6B, 0xCC, 0xDC, 0x18, 0xFF, 0x8C, 0x07, 0xB6 };
-static unsigned char brainpoolP256r1_gx[] = {
-    0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB, 0x2C, 0x4B, 0x48, 0x2F,
-    0xFC, 0x81, 0xB7, 0xAF, 0xB9, 0xDE, 0x27, 0xE1, 0xE3, 0xBD, 0x23, 0xC2,
-    0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE, 0x32, 0x62 };
-static unsigned char brainpoolP256r1_gy[] = {
-    0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD, 0x97, 0xF8, 0x46, 0x1A,
-    0x14, 0x61, 0x1D, 0xC9, 0xC2, 0x77, 0x45, 0x13, 0x2D, 0xED, 0x8E, 0x54,
-    0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04, 0x69, 0x97 };
-static unsigned char brainpoolP256r1_n[] = {
-    0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90,
-    0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7,
-    0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7 };
+#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED)
+static t_uint brainpoolP256r1_p[] = {
+    BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
+    BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
+    BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
+    BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
+};
+static t_uint brainpoolP256r1_a[] = {
+    BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
+    BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
+    BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
+    BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
+};
+static t_uint brainpoolP256r1_b[] = {
+    BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
+    BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
+    BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
+    BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
+};
+static t_uint brainpoolP256r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
+    BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
+    BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
+    BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
+};
+static t_uint brainpoolP256r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
+    BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
+    BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
+    BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
+};
+static t_uint brainpoolP256r1_n[] = {
+    BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
+    BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
+    BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
+    BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
+};
+#endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */
 
 /*
  * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
  */
-static unsigned char brainpoolP384r1_p[] = {
-    0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E,
-    0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4,
-    0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29,
-    0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53 };
-static unsigned char brainpoolP384r1_a[] = {
-    0x7B, 0xC3, 0x82, 0xC6, 0x3D, 0x8C, 0x15, 0x0C, 0x3C, 0x72, 0x08, 0x0A,
-    0xCE, 0x05, 0xAF, 0xA0, 0xC2, 0xBE, 0xA2, 0x8E, 0x4F, 0xB2, 0x27, 0x87,
-    0x13, 0x91, 0x65, 0xEF, 0xBA, 0x91, 0xF9, 0x0F, 0x8A, 0xA5, 0x81, 0x4A,
-    0x50, 0x3A, 0xD4, 0xEB, 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26 };
-static unsigned char brainpoolP384r1_b[] = {
-    0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, 0x8B, 0x39, 0xB5, 0x54,
-    0x16, 0xF0, 0x44, 0x7C, 0x2F, 0xB7, 0x7D, 0xE1, 0x07, 0xDC, 0xD2, 0xA6,
-    0x2E, 0x88, 0x0E, 0xA5, 0x3E, 0xEB, 0x62, 0xD5, 0x7C, 0xB4, 0x39, 0x02,
-    0x95, 0xDB, 0xC9, 0x94, 0x3A, 0xB7, 0x86, 0x96, 0xFA, 0x50, 0x4C, 0x11 };
-static unsigned char brainpoolP384r1_gx[] = {
-    0x1D, 0x1C, 0x64, 0xF0, 0x68, 0xCF, 0x45, 0xFF, 0xA2, 0xA6, 0x3A, 0x81,
-    0xB7, 0xC1, 0x3F, 0x6B, 0x88, 0x47, 0xA3, 0xE7, 0x7E, 0xF1, 0x4F, 0xE3,
-    0xDB, 0x7F, 0xCA, 0xFE, 0x0C, 0xBD, 0x10, 0xE8, 0xE8, 0x26, 0xE0, 0x34,
-    0x36, 0xD6, 0x46, 0xAA, 0xEF, 0x87, 0xB2, 0xE2, 0x47, 0xD4, 0xAF, 0x1E };
-static unsigned char brainpoolP384r1_gy[] = {
-    0x8A, 0xBE, 0x1D, 0x75, 0x20, 0xF9, 0xC2, 0xA4, 0x5C, 0xB1, 0xEB, 0x8E,
-    0x95, 0xCF, 0xD5, 0x52, 0x62, 0xB7, 0x0B, 0x29, 0xFE, 0xEC, 0x58, 0x64,
-    0xE1, 0x9C, 0x05, 0x4F, 0xF9, 0x91, 0x29, 0x28, 0x0E, 0x46, 0x46, 0x21,
-    0x77, 0x91, 0x81, 0x11, 0x42, 0x82, 0x03, 0x41, 0x26, 0x3C, 0x53, 0x15 };
-static unsigned char brainpoolP384r1_n[] = {
-    0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E,
-    0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB3,
-    0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04, 0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF,
-    0x6B, 0x7F, 0xC3, 0x10, 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65 };
+#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED)
+static t_uint brainpoolP384r1_p[] = {
+    BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
+    BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
+    BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
+    BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
+    BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
+    BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
+};
+static t_uint brainpoolP384r1_a[] = {
+    BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
+    BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
+    BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
+    BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
+    BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
+    BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
+};
+static t_uint brainpoolP384r1_b[] = {
+    BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
+    BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
+    BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
+    BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
+    BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
+    BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
+};
+static t_uint brainpoolP384r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
+    BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
+    BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
+    BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
+    BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
+    BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
+};
+static t_uint brainpoolP384r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
+    BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
+    BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
+    BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
+    BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
+    BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
+};
+static t_uint brainpoolP384r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
+    BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
+    BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
+    BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
+    BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
+    BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
+};
+#endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */
 
 /*
  * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
  */
-static unsigned char brainpoolP512r1_p[] = {
-    0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE,
-    0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E,
-    0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00,
-    0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6,
-    0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56,
-    0x58, 0x3A, 0x48, 0xF3 };
-static unsigned char brainpoolP512r1_a[] = {
-    0x78, 0x30, 0xA3, 0x31, 0x8B, 0x60, 0x3B, 0x89, 0xE2, 0x32, 0x71, 0x45,
-    0xAC, 0x23, 0x4C, 0xC5, 0x94, 0xCB, 0xDD, 0x8D, 0x3D, 0xF9, 0x16, 0x10,
-    0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A,
-    0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5,
-    0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D,
-    0x77, 0xFC, 0x94, 0xCA };
-static unsigned char brainpoolP512r1_b[] = {
-    0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC,
-    0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9,
-    0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9,
-    0xE7, 0xC1, 0xAC, 0x4D, 0x77, 0xFC, 0x94, 0xCA, 0xDC, 0x08, 0x3E, 0x67,
-    0x98, 0x40, 0x50, 0xB7, 0x5E, 0xBA, 0xE5, 0xDD, 0x28, 0x09, 0xBD, 0x63,
-    0x80, 0x16, 0xF7, 0x23 };
-static unsigned char brainpoolP512r1_gx[] = {
-    0x81, 0xAE, 0xE4, 0xBD, 0xD8, 0x2E, 0xD9, 0x64, 0x5A, 0x21, 0x32, 0x2E,
-    0x9C, 0x4C, 0x6A, 0x93, 0x85, 0xED, 0x9F, 0x70, 0xB5, 0xD9, 0x16, 0xC1,
-    0xB4, 0x3B, 0x62, 0xEE, 0xF4, 0xD0, 0x09, 0x8E, 0xFF, 0x3B, 0x1F, 0x78,
-    0xE2, 0xD0, 0xD4, 0x8D, 0x50, 0xD1, 0x68, 0x7B, 0x93, 0xB9, 0x7D, 0x5F,
-    0x7C, 0x6D, 0x50, 0x47, 0x40, 0x6A, 0x5E, 0x68, 0x8B, 0x35, 0x22, 0x09,
-    0xBC, 0xB9, 0xF8, 0x22 };
-static unsigned char brainpoolP512r1_gy[] = {
-    0x7D, 0xDE, 0x38, 0x5D, 0x56, 0x63, 0x32, 0xEC, 0xC0, 0xEA, 0xBF, 0xA9,
-    0xCF, 0x78, 0x22, 0xFD, 0xF2, 0x09, 0xF7, 0x00, 0x24, 0xA5, 0x7B, 0x1A,
-    0xA0, 0x00, 0xC5, 0x5B, 0x88, 0x1F, 0x81, 0x11, 0xB2, 0xDC, 0xDE, 0x49,
-    0x4A, 0x5F, 0x48, 0x5E, 0x5B, 0xCA, 0x4B, 0xD8, 0x8A, 0x27, 0x63, 0xAE,
-    0xD1, 0xCA, 0x2B, 0x2F, 0xA8, 0xF0, 0x54, 0x06, 0x78, 0xCD, 0x1E, 0x0F,
-    0x3A, 0xD8, 0x08, 0x92 };
-static unsigned char brainpoolP512r1_n[] = {
-    0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE,
-    0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E,
-    0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41,
-    0x4C, 0xA9, 0x26, 0x19, 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47,
-    0x1D, 0xB1, 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82,
-    0x9C, 0xA9, 0x00, 0x69 };
+#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED)
+static t_uint brainpoolP512r1_p[] = {
+    BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
+    BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
+    BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
+    BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
+    BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
+    BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
+    BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
+    BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
+};
+static t_uint brainpoolP512r1_a[] = {
+    BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
+    BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
+    BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
+    BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
+    BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
+    BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
+    BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
+    BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
+};
+static t_uint brainpoolP512r1_b[] = {
+    BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
+    BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
+    BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
+    BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
+    BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
+    BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
+    BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
+    BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
+};
+static t_uint brainpoolP512r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
+    BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
+    BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
+    BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
+    BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
+    BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
+    BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
+    BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
+};
+static t_uint brainpoolP512r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
+    BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
+    BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
+    BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
+    BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
+    BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
+    BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
+    BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
+};
+static t_uint brainpoolP512r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
+    BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
+    BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
+    BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
+    BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
+    BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
+    BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
+    BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
+};
+#endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */
 
 /*
- * Import an ECP group from binary
+ * Create an MPI from embedded constants
+ * (assumes len is an exact multiple of sizeof t_uint)
  */
-static int ecp_group_read_binary( ecp_group *grp,
-                                  const unsigned char *p,  size_t plen,
-                                  const unsigned char *a,  size_t alen,
-                                  const unsigned char *b,  size_t blen,
-                                  const unsigned char *gx, size_t gxlen,
-                                  const unsigned char *gy, size_t gylen,
-                                  const unsigned char *n,  size_t nlen)
+static inline void ecp_mpi_load( mpi *X, const t_uint *p, size_t len )
 {
-    int ret;
+    X->s = 1;
+    X->n = len / sizeof( t_uint );
+    X->p = (t_uint *) p;
+}
 
-    MPI_CHK( mpi_read_binary( &grp->P, p, plen ) );
+/*
+ * Set an MPI to static value 1
+ */
+static inline void ecp_mpi_set1( mpi *X )
+{
+    static t_uint one[] = { 1 };
+    X->s = 1;
+    X->n = 1;
+    X->p = one;
+}
+
+/*
+ * Make group available from embedded constants
+ */
+static int ecp_group_load( ecp_group *grp,
+                           const t_uint *p,  size_t plen,
+                           const t_uint *a,  size_t alen,
+                           const t_uint *b,  size_t blen,
+                           const t_uint *gx, size_t gxlen,
+                           const t_uint *gy, size_t gylen,
+                           const t_uint *n,  size_t nlen)
+{
+    ecp_mpi_load( &grp->P, p, plen );
     if( a != NULL )
-        MPI_CHK( mpi_read_binary( &grp->A, a, alen ) );
-    else
-        MPI_CHK( mpi_sub_int( &grp->A, &grp->P, 3 ) );
-    MPI_CHK( mpi_read_binary( &grp->B, b, blen ) );
-    MPI_CHK( mpi_read_binary( &grp->N, n, nlen ) );
+        ecp_mpi_load( &grp->A, a, alen );
+    ecp_mpi_load( &grp->B, b, blen );
+    ecp_mpi_load( &grp->N, n, nlen );
 
-    MPI_CHK( mpi_read_binary( &grp->G.X, gx, gxlen ) );
-    MPI_CHK( mpi_read_binary( &grp->G.Y, gy, gylen ) );
-    MPI_CHK( mpi_lset( &grp->G.Z, 1 ) );
+    ecp_mpi_load( &grp->G.X, gx, gxlen );
+    ecp_mpi_load( &grp->G.Y, gy, gylen );
+    ecp_mpi_set1( &grp->G.Z );
 
     grp->pbits = mpi_msb( &grp->P );
     grp->nbits = mpi_msb( &grp->N );
 
-cleanup:
-    if( ret != 0 )
-        ecp_group_free( grp );
+    grp->h = 1;
 
-    return( ret );
+    return( 0 );
 }
 
 #if defined(POLARSSL_ECP_NIST_OPTIM)
@@ -346,7 +557,7 @@
 #define NIST_MODP( P )
 #endif /* POLARSSL_ECP_NIST_OPTIM */
 
-#define LOAD_GROUP( G )     ecp_group_read_binary( grp,     \
+#define LOAD_GROUP_A( G )   ecp_group_load( grp,            \
                             G ## _p,  sizeof( G ## _p  ),   \
                             G ## _a,  sizeof( G ## _a  ),   \
                             G ## _b,  sizeof( G ## _b  ),   \
@@ -354,6 +565,14 @@
                             G ## _gy, sizeof( G ## _gy ),   \
                             G ## _n,  sizeof( G ## _n  ) )
 
+#define LOAD_GROUP( G )     ecp_group_load( grp,            \
+                            G ## _p,  sizeof( G ## _p  ),   \
+                            NULL,     0,                    \
+                            G ## _b,  sizeof( G ## _b  ),   \
+                            G ## _gx, sizeof( G ## _gx ),   \
+                            G ## _gy, sizeof( G ## _gy ),   \
+                            G ## _n,  sizeof( G ## _n  ) )
+
 /*
  * Specialized function for creating the Curve25519 group
  */
@@ -429,17 +648,17 @@
 
 #if defined(POLARSSL_ECP_DP_BP256R1_ENABLED)
         case POLARSSL_ECP_DP_BP256R1:
-            return( LOAD_GROUP( brainpoolP256r1 ) );
+            return( LOAD_GROUP_A( brainpoolP256r1 ) );
 #endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */
 
 #if defined(POLARSSL_ECP_DP_BP384R1_ENABLED)
         case POLARSSL_ECP_DP_BP384R1:
-            return( LOAD_GROUP( brainpoolP384r1 ) );
+            return( LOAD_GROUP_A( brainpoolP384r1 ) );
 #endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */
 
 #if defined(POLARSSL_ECP_DP_BP512R1_ENABLED)
         case POLARSSL_ECP_DP_BP512R1:
-            return( LOAD_GROUP( brainpoolP512r1 ) );
+            return( LOAD_GROUP_A( brainpoolP512r1 ) );
 #endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */
 
 #if defined(POLARSSL_ECP_DP_M255_ENABLED)
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
index 89744a6..c07de49 100644
--- a/library/ssl_ciphersuites.c
+++ b/library/ssl_ciphersuites.c
@@ -128,26 +128,50 @@
     TLS_RSA_WITH_AES_256_GCM_SHA384,
     TLS_RSA_WITH_AES_256_CBC_SHA256,
     TLS_RSA_WITH_AES_256_CBC_SHA,
+    TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
+    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
+    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
+    TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
+    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
+    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
 
     /* All CAMELLIA-256 suites */
     TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,
     TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
     TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
+    TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
+    TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384,
+    TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
+    TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
 
     /* All AES-128 suites */
     TLS_RSA_WITH_AES_128_GCM_SHA256,
     TLS_RSA_WITH_AES_128_CBC_SHA256,
     TLS_RSA_WITH_AES_128_CBC_SHA,
+    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
+    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
+    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
+    TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
+    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
 
     /* All CAMELLIA-128 suites */
     TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,
     TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
     TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
+    TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
+    TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+    TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
+    TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
 
     /* All remaining >= 128-bit suites */
     TLS_RSA_WITH_3DES_EDE_CBC_SHA,
     TLS_RSA_WITH_RC4_128_SHA,
     TLS_RSA_WITH_RC4_128_MD5,
+    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
+    TLS_ECDH_RSA_WITH_RC4_128_SHA,
+    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
 
     /* The RSA PSK suites */
     TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
@@ -198,6 +222,8 @@
     TLS_RSA_WITH_NULL_SHA256,
     TLS_RSA_WITH_NULL_SHA,
     TLS_RSA_WITH_NULL_MD5,
+    TLS_ECDH_RSA_WITH_NULL_SHA,
+    TLS_ECDH_ECDSA_WITH_NULL_SHA,
     TLS_RSA_PSK_WITH_NULL_SHA384,
     TLS_RSA_PSK_WITH_NULL_SHA256,
     TLS_RSA_PSK_WITH_NULL_SHA,
@@ -208,7 +234,7 @@
     0
 };
 
-#define MAX_CIPHERSUITES    128
+#define MAX_CIPHERSUITES    160
 static int supported_ciphersuites[MAX_CIPHERSUITES];
 static int supported_init = 0;
 
@@ -697,6 +723,244 @@
 #endif /* POLARSSL_ARC4_C */
 #endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */
 
+#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED)
+#if defined(POLARSSL_AES_C)
+#if defined(POLARSSL_SHA1_C)
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+    { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA",
+      POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+    { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA",
+      POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+#endif /* POLARSSL_SHA1_C */
+#if defined(POLARSSL_SHA256_C)
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+    { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256",
+      POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+#if defined(POLARSSL_GCM_C)
+    { TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256",
+      POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_GCM_C */
+#endif /* POLARSSL_SHA256_C */
+#if defined(POLARSSL_SHA512_C)
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+    { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384",
+      POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+#if defined(POLARSSL_GCM_C)
+    { TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384",
+      POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_GCM_C */
+#endif /* POLARSSL_SHA512_C */
+#endif /* POLARSSL_AES_C */
+
+#if defined(POLARSSL_CAMELLIA_C)
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+#if defined(POLARSSL_SHA256_C)
+    { TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+      POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_SHA256_C */
+#if defined(POLARSSL_SHA512_C)
+    { TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384",
+      POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_SHA512_C */
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+
+#if defined(POLARSSL_GCM_C)
+#if defined(POLARSSL_SHA256_C)
+    { TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256",
+      POLARSSL_CIPHER_CAMELLIA_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_SHA256_C */
+#if defined(POLARSSL_SHA512_C)
+    { TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384",
+      POLARSSL_CIPHER_CAMELLIA_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_SHA512_C */
+#endif /* POLARSSL_GCM_C */
+#endif /* POLARSSL_CAMELLIA_C */
+
+#if defined(POLARSSL_DES_C)
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+#if defined(POLARSSL_SHA1_C)
+    { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA",
+      POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_SHA1_C */
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+#endif /* POLARSSL_DES_C */
+
+#if defined(POLARSSL_ARC4_C)
+#if defined(POLARSSL_SHA1_C)
+    { TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS-ECDH-RSA-WITH-RC4-128-SHA",
+      POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_SHA1_C */
+#endif /* POLARSSL_ARC4_C */
+
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+#if defined(POLARSSL_SHA1_C)
+    { TLS_ECDH_RSA_WITH_NULL_SHA, "TLS-ECDH-RSA-WITH-NULL-SHA",
+      POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      POLARSSL_CIPHERSUITE_WEAK },
+#endif /* POLARSSL_SHA1_C */
+#endif /* POLARSSL_CIPHER_NULL_CIPHER */
+#endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED */
+
+#if defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+#if defined(POLARSSL_AES_C)
+#if defined(POLARSSL_SHA1_C)
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+    { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA",
+      POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+    { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA",
+      POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+#endif /* POLARSSL_SHA1_C */
+#if defined(POLARSSL_SHA256_C)
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+    { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256",
+      POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+#if defined(POLARSSL_GCM_C)
+    { TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256",
+      POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_GCM_C */
+#endif /* POLARSSL_SHA256_C */
+#if defined(POLARSSL_SHA512_C)
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+    { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384",
+      POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+#if defined(POLARSSL_GCM_C)
+    { TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384",
+      POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_GCM_C */
+#endif /* POLARSSL_SHA512_C */
+#endif /* POLARSSL_AES_C */
+
+#if defined(POLARSSL_CAMELLIA_C)
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+#if defined(POLARSSL_SHA256_C)
+    { TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256",
+      POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_SHA256_C */
+#if defined(POLARSSL_SHA512_C)
+    { TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
+      POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_SHA512_C */
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+
+#if defined(POLARSSL_GCM_C)
+#if defined(POLARSSL_SHA256_C)
+    { TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256",
+      POLARSSL_CIPHER_CAMELLIA_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_SHA256_C */
+#if defined(POLARSSL_SHA512_C)
+    { TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384",
+      POLARSSL_CIPHER_CAMELLIA_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_SHA512_C */
+#endif /* POLARSSL_GCM_C */
+#endif /* POLARSSL_CAMELLIA_C */
+
+#if defined(POLARSSL_DES_C)
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+#if defined(POLARSSL_SHA1_C)
+    { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA",
+      POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_SHA1_C */
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+#endif /* POLARSSL_DES_C */
+
+#if defined(POLARSSL_ARC4_C)
+#if defined(POLARSSL_SHA1_C)
+    { TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS-ECDH-ECDSA-WITH-RC4-128-SHA",
+      POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      0 },
+#endif /* POLARSSL_SHA1_C */
+#endif /* POLARSSL_ARC4_C */
+
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+#if defined(POLARSSL_SHA1_C)
+    { TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS-ECDH-ECDSA-WITH-NULL-SHA",
+      POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      POLARSSL_CIPHERSUITE_WEAK },
+#endif /* POLARSSL_SHA1_C */
+#endif /* POLARSSL_CIPHER_NULL_CIPHER */
+#endif /* POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+
 #if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
 #if defined(POLARSSL_AES_C)
 #if defined(POLARSSL_GCM_C)
@@ -1376,6 +1640,10 @@
         case POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA:
             return( POLARSSL_PK_ECDSA );
 
+        case POLARSSL_KEY_EXCHANGE_ECDH_RSA:
+        case POLARSSL_KEY_EXCHANGE_ECDH_ECDSA:
+            return( POLARSSL_PK_ECKEY );
+
         default:
             return( POLARSSL_PK_NONE );
     }
@@ -1389,6 +1657,8 @@
         case POLARSSL_KEY_EXCHANGE_ECDHE_RSA:
         case POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA:
         case POLARSSL_KEY_EXCHANGE_ECDHE_PSK:
+        case POLARSSL_KEY_EXCHANGE_ECDH_RSA:
+        case POLARSSL_KEY_EXCHANGE_ECDH_ECDSA:
             return( 1 );
 
         default:
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 0f9a731..76c943d 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1115,6 +1115,29 @@
 
 #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
     defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
+    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
+    defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
+    defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+static int ssl_check_server_ecdh_params( const ssl_context *ssl )
+{
+    SSL_DEBUG_MSG( 2, ( "ECDH curve size: %d",
+                        (int) ssl->handshake->ecdh_ctx.grp.nbits ) );
+
+    if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
+        ssl->handshake->ecdh_ctx.grp.nbits > 521 )
+    {
+        return( -1 );
+    }
+
+    SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
+
+    return( 0 );
+}
+#endif
+
+
+#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
+    defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
     defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
 static int ssl_parse_server_ecdh_params( ssl_context *ssl,
                                          unsigned char **p,
@@ -1137,18 +1160,12 @@
         return( ret );
     }
 
-    SSL_DEBUG_MSG( 2, ( "ECDH curve size: %d",
-                        (int) ssl->handshake->ecdh_ctx.grp.nbits ) );
-
-    if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
-        ssl->handshake->ecdh_ctx.grp.nbits > 521 )
+    if( ssl_check_server_ecdh_params( ssl ) != 0 )
     {
         SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDH length)" ) );
         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
     }
 
-    SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
-
     return( ret );
 }
 #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
@@ -1307,6 +1324,41 @@
           POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
+
+#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+    defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+static int ssl_get_ecdh_params_from_cert( ssl_context *ssl )
+{
+    int ret;
+    const ecp_keypair *peer_key;
+
+    if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,
+                     POLARSSL_PK_ECKEY ) )
+    {
+        SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
+        return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
+    }
+
+    peer_key = pk_ec( ssl->session_negotiate->peer_cert->pk );
+
+    if( ( ret = ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key,
+                                 POLARSSL_ECDH_THEIRS ) ) != 0 )
+    {
+        SSL_DEBUG_RET( 1, ( "ecdh_get_params" ), ret );
+        return( ret );
+    }
+
+    if( ssl_check_server_ecdh_params( ssl ) != 0 )
+    {
+        SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH length)" ) );
+        return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
+    }
+
+    return( ret );
+}
+#endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
+          POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+
 static int ssl_parse_server_key_exchange( ssl_context *ssl )
 {
     int ret;
@@ -1335,6 +1387,21 @@
     ((void) end);
 #endif
 
+#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+    defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA )
+    {
+        ssl_get_ecdh_params_from_cert( ssl );
+
+        SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
+        ssl->state++;
+        return( 0 );
+    }
+    ((void) p);
+    ((void) end);
+#endif
+
     if( ( ret = ssl_read_record( ssl ) ) != 0 )
     {
         SSL_DEBUG_RET( 1, "ssl_read_record", ret );
@@ -1852,9 +1919,13 @@
     else
 #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED */
 #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+    defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
+    defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
+    defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
     if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA ||
-        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA )
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA )
     {
         /*
          * ECDH key exchange -- send client public value
@@ -1887,7 +1958,9 @@
     }
     else
 #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+          POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
+          POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
+          POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
 #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
     if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
         ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ||
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 0c6c0d7..0abded1 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1962,6 +1962,31 @@
           !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
           !POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
 
+#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+    defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+static int ssl_get_ecdh_params_from_cert( ssl_context *ssl )
+{
+    int ret;
+
+    if( ! pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_ECKEY ) )
+    {
+        SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
+        return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
+    }
+
+    if( ( ret = ecdh_get_params( &ssl->handshake->ecdh_ctx,
+                                 pk_ec( *ssl_own_key( ssl ) ),
+                                 POLARSSL_ECDH_OURS ) ) != 0 )
+    {
+        SSL_DEBUG_RET( 1, ( "ecdh_get_params" ), ret );
+        return( ret );
+    }
+
+    return( 0 );
+}
+#endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
+          POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+
 static int ssl_write_server_key_exchange( ssl_context *ssl )
 {
     int ret;
@@ -1983,6 +2008,9 @@
 
     SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
 
+#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) ||                           \
+    defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
+    defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
     if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA ||
         ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
         ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK )
@@ -1991,6 +2019,20 @@
         ssl->state++;
         return( 0 );
     }
+#endif
+
+#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+    defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA )
+    {
+        ssl_get_ecdh_params_from_cert( ssl );
+
+        SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
+        ssl->state++;
+        return( 0 );
+    }
+#endif
 
 #if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
     defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
@@ -2533,9 +2575,13 @@
     else
 #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED */
 #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+    defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
+    defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
+    defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
     if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA ||
-        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA )
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA )
     {
         size_t n = ssl->in_msg[3];
 
@@ -2555,6 +2601,10 @@
 
         SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp );
 
+        SSL_DEBUG_MSG( 0, ( "ECDH: id %d", ssl->handshake->ecdh_ctx.grp.id ) );
+        SSL_DEBUG_ECP( 0, "ECDH: Q  ", &ssl->handshake->ecdh_ctx.Q );
+        SSL_DEBUG_MPI( 0, "ECDH: d  ", &ssl->handshake->ecdh_ctx.d );
+
         if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
                                       &ssl->handshake->pmslen,
                                        ssl->handshake->premaster,
@@ -2569,7 +2619,9 @@
     }
     else
 #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+          POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
+          POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
+          POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
 #if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
     if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK )
     {
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index a903b3e..9abc9be 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2316,11 +2316,13 @@
 /*
  * Handshake functions
  */
-#if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED)       && \
-    !defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)   && \
-    !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED)   && \
-    !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
-    !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED)         && \
+    !defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)     && \
+    !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED)     && \
+    !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED)   && \
+    !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
+    !defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED)    && \
+    !defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
 int ssl_write_certificate( ssl_context *ssl )
 {
     int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
@@ -2649,9 +2651,13 @@
 
     return( ret );
 }
-#endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED &&
-          !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED &&
-          !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
+#endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED
+          !POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED
+          !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED
+          !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+          !POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+          !POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED
+          !POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
 
 int ssl_write_change_cipher_spec( ssl_context *ssl )
 {
@@ -3449,17 +3455,24 @@
         return( POLARSSL_ERR_SSL_MALLOC_FAILED );
 
     if( ( ret = ssl->f_rng( ssl->p_rng, tkeys->key_name, 16 ) ) != 0 )
+    {
+        polarssl_free( tkeys );
         return( ret );
+    }
 
     if( ( ret = ssl->f_rng( ssl->p_rng, buf, 16 ) ) != 0 ||
         ( ret = aes_setkey_enc( &tkeys->enc, buf, 128 ) ) != 0 ||
         ( ret = aes_setkey_dec( &tkeys->dec, buf, 128 ) ) != 0 )
     {
-            return( ret );
+        polarssl_free( tkeys );
+        return( ret );
     }
 
     if( ( ret = ssl->f_rng( ssl->p_rng, tkeys->mac_key, 16 ) ) != 0 )
+    {
+        polarssl_free( tkeys );
         return( ret );
+    }
 
     ssl->ticket_keys = tkeys;
 
@@ -3817,7 +3830,7 @@
 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
 int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code )
 {
-    if( mfl_code >= sizeof( mfl_code_to_length ) ||
+    if( mfl_code >= SSL_MAX_FRAG_LEN_INVALID ||
         mfl_code_to_length[mfl_code] > SSL_MAX_CONTENT_LEN )
     {
         return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index 34219c5..f91a2d4 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -298,6 +298,8 @@
             TIME_AND_TSC( title,
                     gcm_crypt_and_tag( &gcm, GCM_ENCRYPT, BUFSIZE, tmp,
                         12, NULL, 0, buf, buf, 16, tmp ) );
+
+            gcm_free( &gcm );
         }
     }
 #endif
diff --git a/tests/compat.sh b/tests/compat.sh
index 136efa0..ecc2e58 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -120,6 +120,9 @@
 for TYPE in $TYPES;
 do
 
+P_CIPHERS=""
+O_CIPHERS=""
+
 case $TYPE in
 
     "ECDSA")
@@ -129,21 +132,34 @@
         O_SERVER_ARGS="$O_SERVER_BASE -cert data_files/server5.crt -key data_files/server5.key"
         O_CLIENT_ARGS="$O_CLIENT_BASE -cert data_files/server6.crt -key data_files/server6.key"
 
-        P_CIPHERS="                                 \
-            TLS-ECDHE-ECDSA-WITH-NULL-SHA           \
-            TLS-ECDHE-ECDSA-WITH-RC4-128-SHA        \
-            TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA   \
-            TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA    \
-            TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA    \
-            "
+        if [ "$MODE" != "ssl3" ];
+        then
+            P_CIPHERS="$P_CIPHERS                       \
+                TLS-ECDHE-ECDSA-WITH-NULL-SHA           \
+                TLS-ECDHE-ECDSA-WITH-RC4-128-SHA        \
+                TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA   \
+                TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA    \
+                TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA    \
+                TLS-ECDH-ECDSA-WITH-NULL-SHA            \
+                TLS-ECDH-ECDSA-WITH-RC4-128-SHA         \
+                TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA    \
+                TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA     \
+                TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA     \
+                "
 
-        O_CIPHERS="                         \
-            ECDHE-ECDSA-NULL-SHA            \
-            ECDHE-ECDSA-RC4-SHA             \
-            ECDHE-ECDSA-DES-CBC3-SHA        \
-            ECDHE-ECDSA-AES128-SHA          \
-            ECDHE-ECDSA-AES256-SHA          \
-            "
+            O_CIPHERS="$O_CIPHERS               \
+                ECDHE-ECDSA-NULL-SHA            \
+                ECDHE-ECDSA-RC4-SHA             \
+                ECDHE-ECDSA-DES-CBC3-SHA        \
+                ECDHE-ECDSA-AES128-SHA          \
+                ECDHE-ECDSA-AES256-SHA          \
+                ECDH-ECDSA-NULL-SHA             \
+                ECDH-ECDSA-RC4-SHA              \
+                ECDH-ECDSA-DES-CBC3-SHA         \
+                ECDH-ECDSA-AES128-SHA           \
+                ECDH-ECDSA-AES256-SHA           \
+                "
+        fi
 
         if [ "$MODE" = "tls1_2" ];
         then
@@ -152,13 +168,21 @@
                 TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384         \
                 TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256         \
                 TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384         \
+                TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256          \
+                TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384          \
+                TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256          \
+                TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384          \
                 "
 
-            O_CIPHERS="                         \
+            O_CIPHERS="$O_CIPHERS               \
                 ECDHE-ECDSA-AES128-SHA256       \
                 ECDHE-ECDSA-AES256-SHA384       \
                 ECDHE-ECDSA-AES128-GCM-SHA256   \
                 ECDHE-ECDSA-AES256-GCM-SHA384   \
+                ECDH-ECDSA-AES128-SHA256        \
+                ECDH-ECDSA-AES256-SHA384        \
+                ECDH-ECDSA-AES128-GCM-SHA256    \
+                ECDH-ECDSA-AES256-GCM-SHA384    \
                 "
         fi
 
@@ -171,7 +195,7 @@
         O_SERVER_ARGS="$O_SERVER_BASE -cert data_files/server1.crt -key data_files/server1.key"
         O_CLIENT_ARGS="$O_CLIENT_BASE -cert data_files/server2.crt -key data_files/server2.key"
 
-        P_CIPHERS="                                 \
+        P_CIPHERS="$P_CIPHERS                       \
             TLS-DHE-RSA-WITH-AES-128-CBC-SHA        \
             TLS-DHE-RSA-WITH-AES-256-CBC-SHA        \
             TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA   \
@@ -188,14 +212,9 @@
             TLS-RSA-WITH-NULL-SHA                   \
             TLS-RSA-WITH-DES-CBC-SHA                \
             TLS-DHE-RSA-WITH-DES-CBC-SHA            \
-            TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA      \
-            TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA      \
-            TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA     \
-            TLS-ECDHE-RSA-WITH-RC4-128-SHA          \
-            TLS-ECDHE-RSA-WITH-NULL-SHA             \
             "
 
-        O_CIPHERS="                         \
+        O_CIPHERS="$O_CIPHERS               \
             DHE-RSA-AES128-SHA              \
             DHE-RSA-AES256-SHA              \
             DHE-RSA-CAMELLIA128-SHA         \
@@ -212,13 +231,27 @@
             NULL-SHA                        \
             DES-CBC-SHA                     \
             EDH-RSA-DES-CBC-SHA             \
-            ECDHE-RSA-AES256-SHA            \
-            ECDHE-RSA-AES128-SHA            \
-            ECDHE-RSA-DES-CBC3-SHA          \
-            ECDHE-RSA-RC4-SHA               \
-            ECDHE-RSA-NULL-SHA              \
             "
 
+        if [ "$MODE" != "ssl3" ];
+        then
+            P_CIPHERS="$P_CIPHERS                       \
+                TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA      \
+                TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA      \
+                TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA     \
+                TLS-ECDHE-RSA-WITH-RC4-128-SHA          \
+                TLS-ECDHE-RSA-WITH-NULL-SHA             \
+                "
+
+            O_CIPHERS="$O_CIPHERS               \
+                ECDHE-RSA-AES256-SHA            \
+                ECDHE-RSA-AES128-SHA            \
+                ECDHE-RSA-DES-CBC3-SHA          \
+                ECDHE-RSA-RC4-SHA               \
+                ECDHE-RSA-NULL-SHA              \
+                "
+        fi
+
         if [ "$MODE" = "tls1_2" ];
         then
             P_CIPHERS="$P_CIPHERS                       \
@@ -264,14 +297,14 @@
         O_SERVER_ARGS="$O_SERVER_BASE -psk 6162636465666768696a6b6c6d6e6f70 -cert data_files/server1.crt -key data_files/server1.key"
         O_CLIENT_ARGS="$O_CLIENT_BASE -psk 6162636465666768696a6b6c6d6e6f70"
 
-        P_CIPHERS="                                 \
+        P_CIPHERS="$P_CIPHERS                       \
             TLS-PSK-WITH-RC4-128-SHA                \
             TLS-PSK-WITH-3DES-EDE-CBC-SHA           \
             TLS-PSK-WITH-AES-128-CBC-SHA            \
             TLS-PSK-WITH-AES-256-CBC-SHA            \
             "
 
-        O_CIPHERS="                         \
+        O_CIPHERS="$O_CIPHERS               \
             PSK-RC4-SHA                     \
             PSK-3DES-EDE-CBC-SHA            \
             PSK-AES128-CBC-SHA              \
@@ -374,6 +407,18 @@
             P_CIPHERS="$P_CIPHERS                               \
                 TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256    \
                 TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384    \
+                TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256     \
+                TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384     \
+                "
+        fi
+
+        if [ "$MODE" = "tls1_2" ];
+        then
+            P_CIPHERS="$P_CIPHERS                               \
+                TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256    \
+                TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384    \
+                TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256     \
+                TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384     \
                 "
         fi