Add ecp_supported_curves and simplify some code
diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h
index 922d5da..b43278d 100644
--- a/include/polarssl/ecp.h
+++ b/include/polarssl/ecp.h
@@ -54,14 +54,29 @@
 typedef enum
 {
     POLARSSL_ECP_DP_NONE = 0,
-    POLARSSL_ECP_DP_SECP192R1,      /* 192-bits NIST curve  */
-    POLARSSL_ECP_DP_SECP224R1,      /* 224-bits NIST curve  */
-    POLARSSL_ECP_DP_SECP256R1,      /* 256-bits NIST curve  */
-    POLARSSL_ECP_DP_SECP384R1,      /* 384-bits NIST curve  */
-    POLARSSL_ECP_DP_SECP521R1,      /* 521-bits NIST curve  */
+    POLARSSL_ECP_DP_SECP192R1,      /*!< 192-bits NIST curve  */
+    POLARSSL_ECP_DP_SECP224R1,      /*!< 224-bits NIST curve  */
+    POLARSSL_ECP_DP_SECP256R1,      /*!< 256-bits NIST curve  */
+    POLARSSL_ECP_DP_SECP384R1,      /*!< 384-bits NIST curve  */
+    POLARSSL_ECP_DP_SECP521R1,      /*!< 521-bits NIST curve  */
 } ecp_group_id;
 
 /**
+ * Curve information for use by the SSL module
+ */
+typedef struct
+{
+    ecp_group_id grp_id;    /*!< Internal identifier    */
+    uint16_t name;          /*!< TLS NamedCurve value   */
+    uint16_t size;          /*!< Curve size in bits     */
+} ecp_curve_info;
+
+/**
+ * List of supported curves
+ */
+extern ecp_curve_info ecp_supported_curves[];
+
+/**
  * \brief           ECP point structure (jacobian coordinates)
  *
  * \note            All functions expect and return points satisfying
@@ -346,7 +361,7 @@
  * \return          The associated TLS NamedCurve value on success,
  *                  0 on failure.
  */
-unsigned int ecp_named_curve_from_grp_id( ecp_group_id id );
+uint16_t ecp_named_curve_from_grp_id( ecp_group_id id );
 
 /**
  * \brief           Get an internal group identifier from a TLS NamedCurve value
@@ -356,7 +371,7 @@
  * \return          The associated POLARSSL_ECP_DP_XXX identifer on success,
  *                  POLARSSL_ECP_DP_NONE on failure.
  */
-ecp_group_id ecp_grp_id_from_named_curve( unsigned int curve );
+ecp_group_id ecp_grp_id_from_named_curve( uint16_t curve );
 
 /**
  * \brief           Import a point from a TLS ECPoint record
diff --git a/library/ecp.c b/library/ecp.c
index 8efa183..fef9ab6 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -68,6 +68,32 @@
 #endif
 
 /*
+ * List of supported curves:
+ *  - internal ID
+ *  - TLS NamedCurve number (RFC 4492 section 5.1.1)
+ *  - size in bits
+ */
+ecp_curve_info ecp_supported_curves[] =
+{
+#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
+    { POLARSSL_ECP_DP_SECP521R1,    25,     521, },
+#endif
+#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
+    { POLARSSL_ECP_DP_SECP384R1,    24,     384, },
+#endif
+#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
+    { POLARSSL_ECP_DP_SECP256R1,    23,     256, },
+#endif
+#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
+    { POLARSSL_ECP_DP_SECP224R1,    21,     224, },
+#endif
+#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
+    { POLARSSL_ECP_DP_SECP192R1,    19,     192, },
+#endif
+    { POLARSSL_ECP_DP_NONE,          0,     0 },
+};
+
+/*
  * Initialize (the components of) a point
  */
 void ecp_point_init( ecp_point *pt )
@@ -720,54 +746,42 @@
     return 0;
 }
 
-/* Hard-coded values are temporary, will be reimplemented soon */
-ecp_group_id ecp_grp_id_from_named_curve( unsigned int curve )
+/*
+ * Get the internal identifer from the TLS name
+ */
+ecp_group_id ecp_grp_id_from_named_curve( uint16_t name )
 {
-    switch( curve )
+    ecp_curve_info *curve_info;
+
+    for( curve_info = ecp_supported_curves;
+         curve_info->grp_id != POLARSSL_ECP_DP_NONE;
+         curve_info++ )
     {
-        case 19:
-            return( POLARSSL_ECP_DP_SECP192R1 );
-
-        case 21:
-            return( POLARSSL_ECP_DP_SECP224R1 );
-
-        case 23:
-            return( POLARSSL_ECP_DP_SECP256R1 );
-
-        case 24:
-            return( POLARSSL_ECP_DP_SECP384R1 );
-
-        case 25:
-            return( POLARSSL_ECP_DP_SECP521R1 );
-
-        default:
-            return( POLARSSL_ECP_DP_NONE );
+        if( curve_info->name == name )
+            return( curve_info->grp_id );
     }
+
+    return( POLARSSL_ECP_DP_NONE );
 }
 
-unsigned int ecp_named_curve_from_grp_id( ecp_group_id id )
+/*
+ * Get the TLS name for the internal identifer
+ */
+uint16_t ecp_named_curve_from_grp_id( ecp_group_id id )
 {
-    switch( id )
+    ecp_curve_info *curve_info;
+
+    for( curve_info = ecp_supported_curves;
+         curve_info->grp_id != POLARSSL_ECP_DP_NONE;
+         curve_info++ )
     {
-        case POLARSSL_ECP_DP_SECP192R1:
-            return( 19 );
-
-        case POLARSSL_ECP_DP_SECP224R1:
-            return( 21 );
-
-        case POLARSSL_ECP_DP_SECP256R1:
-            return( 23 );
-
-        case POLARSSL_ECP_DP_SECP384R1:
-            return( 24 );
-
-        case POLARSSL_ECP_DP_SECP521R1:
-            return( 25 );
-
-        default:
-            return( 0 );
+        if( curve_info->grp_id == id )
+            return( curve_info->name );
     }
+
+    return( 0 );
 }
+
 /*
  * Fast mod-p functions expect their argument to be in the 0..p^2 range.
  *
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index a899aff..300001e 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -233,32 +233,20 @@
     unsigned char *p = buf;
     unsigned char elliptic_curve_list[20];
     size_t elliptic_curve_len = 0;
+    ecp_curve_info *curve;
     ((void) ssl);
 
     *olen = 0;
 
     SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) );
 
-#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
-    elliptic_curve_list[elliptic_curve_len++] = 0x00;
-    elliptic_curve_list[elliptic_curve_len++] = ecp_named_curve_from_grp_id( POLARSSL_ECP_DP_SECP521R1 );
-#endif
-#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
-    elliptic_curve_list[elliptic_curve_len++] = 0x00;
-    elliptic_curve_list[elliptic_curve_len++] = ecp_named_curve_from_grp_id( POLARSSL_ECP_DP_SECP384R1 );
-#endif
-#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
-    elliptic_curve_list[elliptic_curve_len++] = 0x00;
-    elliptic_curve_list[elliptic_curve_len++] = ecp_named_curve_from_grp_id( POLARSSL_ECP_DP_SECP256R1 );
-#endif
-#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
-    elliptic_curve_list[elliptic_curve_len++] = 0x00;
-    elliptic_curve_list[elliptic_curve_len++] = ecp_named_curve_from_grp_id( POLARSSL_ECP_DP_SECP224R1 );
-#endif
-#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
-    elliptic_curve_list[elliptic_curve_len++] = 0x00;
-    elliptic_curve_list[elliptic_curve_len++] = ecp_named_curve_from_grp_id( POLARSSL_ECP_DP_SECP192R1 );
-#endif
+    for( curve = ecp_supported_curves;
+         curve->grp_id != POLARSSL_ECP_DP_NONE;
+         curve++ )
+    {
+        elliptic_curve_list[elliptic_curve_len++] = curve->name >> 8;
+        elliptic_curve_list[elliptic_curve_len++] = curve->name & 0xFF;
+    }
 
     if( elliptic_curve_len == 0 )
         return;
@@ -1134,10 +1122,13 @@
     if( ( ret = ecdh_read_params( &ssl->handshake->ecdh_ctx,
                                   (const unsigned char **) p, end ) ) != 0 )
     {
-        SSL_DEBUG_RET( 2, ( "ecdh_read_params" ), ret );
+        SSL_DEBUG_RET( 1, ( "ecdh_read_params" ), ret );
         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 )
     {
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index bb8d3e9..88afc84 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -517,41 +517,12 @@
     while( list_size > 0 )
     {
         grp_id = ecp_grp_id_from_named_curve( ( p[0] << 8 ) | p[1] );
-#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
-        if( grp_id == POLARSSL_ECP_DP_SECP192R1 )
+
+        if( grp_id != POLARSSL_ECP_DP_NONE )
         {
             ssl->handshake->ec_curve = grp_id;
             return( 0 );
         }
-#endif
-#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
-        if( grp_id == POLARSSL_ECP_DP_SECP224R1 )
-        {
-            ssl->handshake->ec_curve = grp_id;
-            return( 0 );
-        }
-#endif
-#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
-        if( grp_id == POLARSSL_ECP_DP_SECP256R1 )
-        {
-            ssl->handshake->ec_curve = grp_id;
-            return( 0 );
-        }
-#endif
-#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
-        if( grp_id == POLARSSL_ECP_DP_SECP384R1 )
-        {
-            ssl->handshake->ec_curve = grp_id;
-            return( 0 );
-        }
-#endif
-#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
-        if( grp_id == POLARSSL_ECP_DP_SECP521R1 )
-        {
-            ssl->handshake->ec_curve = grp_id;
-            return( 0 );
-        }
-#endif
 
         list_size -= 2;
         p += 2;
@@ -1939,6 +1910,9 @@
             return( ret );
         }
 
+        SSL_DEBUG_MSG( 2, ( "ECDH curve size: %d",
+                            (int) ssl->handshake->ecdh_ctx.grp.nbits ) );
+
         if( ( ret = ecdh_make_params( &ssl->handshake->ecdh_ctx,
                                       &len,
                                       p,
diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c
index a88bf1f..d6200f1 100644
--- a/programs/pkey/ecdsa.c
+++ b/programs/pkey/ecdsa.c
@@ -38,30 +38,18 @@
  */
 
 #if !defined(ECPARAMS)
-#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
-#define ECPARAMS    POLARSSL_ECP_DP_SECP192R1
-#elif defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
-#define ECPARAMS    POLARSSL_ECP_DP_SECP224R1
-#elif defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
-#define ECPARAMS    POLARSSL_ECP_DP_SECP256R1
-#elif defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
-#define ECPARAMS    POLARSSL_ECP_DP_SECP384R1
-#elif defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
-#define ECPARAMS    POLARSSL_ECP_DP_SECP521R1
+#define ECPARAMS    ecp_supported_curves[0].grp_id
 #endif
-#endif /* !defined(ECPARAMS) */
 
 #if !defined(POLARSSL_ECDSA_C) || \
-    !defined(POLARSSL_ENTROPY_C) || !defined(POLARSSL_CTR_DRBG_C) || \
-    !defined(ECPARAMS)
+    !defined(POLARSSL_ENTROPY_C) || !defined(POLARSSL_CTR_DRBG_C)
 int main( int argc, char *argv[] )
 {
     ((void) argc);
     ((void) argv);
 
     printf("POLARSSL_ECDSA_C and/or "
-           "POLARSSL_ENTROPY_C and/or POLARSSL_CTR_DRBG_C not defined,"
-           "and/or no EC domain parameter available\n" );
+           "POLARSSL_ENTROPY_C and/or POLARSSL_CTR_DRBG_C not defined\n"
     return( 0 );
 }
 #else