Dissociate TLS and internal EC curve identifiers

Allows to add new curves before they get a TLS number
diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h
index 346b3a8..922d5da 100644
--- a/include/polarssl/ecp.h
+++ b/include/polarssl/ecp.h
@@ -43,6 +43,25 @@
 #endif
 
 /**
+ * Domain parameters (curve, subgroup and generator) identifiers.
+ *
+ * Only curves over prime fields are supported.
+ *
+ * \warning This library does not support validation of arbitrary domain
+ * parameters. Therefore, only well-known domain parameters from trusted
+ * sources should be used. See ecp_use_known_dp().
+ */
+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  */
+} ecp_group_id;
+
+/**
  * \brief           ECP point structure (jacobian coordinates)
  *
  * \note            All functions expect and return points satisfying
@@ -59,11 +78,6 @@
 }
 ecp_point;
 
-/*
- * RFC 4492 defines an enum NamedCurve with two-bytes values
- */
-typedef uint16_t ecp_group_id;
-
 /**
  * \brief           ECP group structure
  *
@@ -108,27 +122,6 @@
 ecp_keypair;
 
 /**
- * RFC 5114 defines a number of standardized ECP groups for use with TLS.
- *
- * These also are the NIST-recommended ECP groups, are the random ECP groups
- * recommended by SECG, and include the two groups used by NSA Suite B.
- * There are known as secpLLLr1 with LLL = 192, 224, 256, 384, 521.
- *
- * \warning This library does not support validation of arbitrary domain
- * parameters. Therefore, only well-known domain parameters from trusted
- * sources should be used. See ecp_use_known_dp().
- *
- * \note The values are taken from RFC 4492's enum NamedCurve,
- * except NONE which is used to denote uninitialized groups.
- */
-#define POLARSSL_ECP_DP_NONE        0
-#define POLARSSL_ECP_DP_SECP192R1   19
-#define POLARSSL_ECP_DP_SECP224R1   21
-#define POLARSSL_ECP_DP_SECP256R1   23
-#define POLARSSL_ECP_DP_SECP384R1   24
-#define POLARSSL_ECP_DP_SECP521R1   25
-
-/**
  * Maximum size of the groups (that is, of N and P)
  */
 #define POLARSSL_ECP_MAX_BITS     521
@@ -311,7 +304,7 @@
  *
  * \return          O if successful,
  *                  POLARSSL_ERR_MPI_XXX if initialization failed
- *                  POLARSSL_ERR_ECP_GENERIC if index is out of range
+ *                  POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups
  *
  * \note            Index should be a value of RFC 4492's enum NamdeCurve,
  *                  possibly in the form of a POLARSSL_ECP_DP_XXX macro.
@@ -346,6 +339,26 @@
                          unsigned char *buf, size_t blen );
 
 /**
+ * \brief           Get a TLS NamedCurve value from an internal group identifier
+ *
+ * \param grp_id    A POLARSSL_ECP_DP_XXX value
+ *
+ * \return          The associated TLS NamedCurve value on success,
+ *                  0 on failure.
+ */
+unsigned int ecp_named_curve_from_grp_id( ecp_group_id id );
+
+/**
+ * \brief           Get an internal group identifier from a TLS NamedCurve value
+ *
+ * \param curve     A value from TLS's enum NamedCurve
+ *
+ * \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 );
+
+/**
  * \brief           Import a point from a TLS ECPoint record
  *
  * \param grp       ECP group used
diff --git a/library/ecp.c b/library/ecp.c
index a80ddac..8efa183 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -655,9 +655,11 @@
                         SECP521R1_P, SECP521R1_B,
                         SECP521R1_GX, SECP521R1_GY, SECP521R1_N ) );
 #endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */
-    }
 
-    return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE );
+        default:
+            grp->id = POLARSSL_ECP_DP_NONE;
+            return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE );
+    }
 }
 
 /*
@@ -665,7 +667,7 @@
  */
 int ecp_tls_read_group( ecp_group *grp, const unsigned char **buf, size_t len )
 {
-    ecp_group_id id;
+    unsigned int named_curve;
 
     /*
      * We expect at least three bytes (see below)
@@ -682,10 +684,10 @@
     /*
      * Next two bytes are the namedcurve value
      */
-    id = *(*buf)++;
-    id <<= 8;
-    id |= *(*buf)++;
-    return ecp_use_known_dp( grp, id );
+    named_curve = *(*buf)++;
+    named_curve <<= 8;
+    named_curve |= *(*buf)++;
+    return ecp_use_known_dp( grp, ecp_grp_id_from_named_curve( named_curve ) );
 }
 
 /*
@@ -694,6 +696,8 @@
 int ecp_tls_write_group( const ecp_group *grp, size_t *olen,
                          unsigned char *buf, size_t blen )
 {
+    unsigned int named_curve;
+
     /*
      * We are going to write 3 bytes (see below)
      */
@@ -709,12 +713,61 @@
     /*
      * Next two bytes are the namedcurve value
      */
-    buf[0] = grp->id >> 8;
-    buf[1] = grp->id & 0xFF;
+    named_curve = ecp_named_curve_from_grp_id( grp->id );
+    buf[0] = named_curve >> 8;
+    buf[1] = named_curve & 0xFF;
 
     return 0;
 }
 
+/* Hard-coded values are temporary, will be reimplemented soon */
+ecp_group_id ecp_grp_id_from_named_curve( unsigned int curve )
+{
+    switch( curve )
+    {
+        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 );
+    }
+}
+
+unsigned int ecp_named_curve_from_grp_id( ecp_group_id id )
+{
+    switch( id )
+    {
+        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 );
+    }
+}
 /*
  * 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 e855377..a899aff 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -241,23 +241,23 @@
 
 #if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
     elliptic_curve_list[elliptic_curve_len++] = 0x00;
-    elliptic_curve_list[elliptic_curve_len++] = POLARSSL_ECP_DP_SECP521R1;
+    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++] = POLARSSL_ECP_DP_SECP384R1;
+    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++] = POLARSSL_ECP_DP_SECP256R1;
+    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++] = POLARSSL_ECP_DP_SECP224R1;
+    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++] = POLARSSL_ECP_DP_SECP192R1;
+    elliptic_curve_list[elliptic_curve_len++] = ecp_named_curve_from_grp_id( POLARSSL_ECP_DP_SECP192R1 );
 #endif
 
     if( elliptic_curve_len == 0 )
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 040196d..bb8d3e9 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -503,6 +503,7 @@
 {
     size_t list_size;
     const unsigned char *p;
+    ecp_group_id grp_id;
 
     list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
     if( list_size + 2 != len ||
@@ -515,38 +516,39 @@
     p = buf + 2;
     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( p[0] == 0x00 && p[1] == POLARSSL_ECP_DP_SECP192R1 )
+        if( grp_id == POLARSSL_ECP_DP_SECP192R1 )
         {
-            ssl->handshake->ec_curve = p[1];
+            ssl->handshake->ec_curve = grp_id;
             return( 0 );
         }
 #endif
 #if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
-        if( p[0] == 0x00 && p[1] == POLARSSL_ECP_DP_SECP224R1 )
+        if( grp_id == POLARSSL_ECP_DP_SECP224R1 )
         {
-            ssl->handshake->ec_curve = p[1];
+            ssl->handshake->ec_curve = grp_id;
             return( 0 );
         }
 #endif
 #if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
-        if( p[0] == 0x00 && p[1] == POLARSSL_ECP_DP_SECP256R1 )
+        if( grp_id == POLARSSL_ECP_DP_SECP256R1 )
         {
-            ssl->handshake->ec_curve = p[1];
+            ssl->handshake->ec_curve = grp_id;
             return( 0 );
         }
 #endif
 #if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
-        if( p[0] == 0x00 && p[1] == POLARSSL_ECP_DP_SECP384R1 )
+        if( grp_id == POLARSSL_ECP_DP_SECP384R1 )
         {
-            ssl->handshake->ec_curve = p[1];
+            ssl->handshake->ec_curve = grp_id;
             return( 0 );
         }
 #endif
 #if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
-        if( p[0] == 0x00 && p[1] == POLARSSL_ECP_DP_SECP521R1 )
+        if( grp_id == POLARSSL_ECP_DP_SECP521R1 )
         {
-            ssl->handshake->ec_curve = p[1];
+            ssl->handshake->ec_curve = grp_id;
             return( 0 );
         }
 #endif