Make ECP error codes more specific
diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h
index b43278d..7a58011 100644
--- a/include/polarssl/ecp.h
+++ b/include/polarssl/ecp.h
@@ -34,9 +34,11 @@
  */
 #define POLARSSL_ERR_ECP_BAD_INPUT_DATA                    -0x4F80  /**< Bad input parameters to function. */
 #define POLARSSL_ERR_ECP_BUFFER_TOO_SMALL                  -0x4F00  /**< The buffer is too small to write to. */
-#define POLARSSL_ERR_ECP_GENERIC                           -0x4E80  /**< Generic ECP error. */
-#define POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE               -0x4E00  /**< Requested curve not available. */
+#define POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE               -0x4E80  /**< Requested curve not available. */
 #define POLARSSL_ERR_ECP_VERIFY_FAILED                     -0x4E00  /**< The signature is not valid. */
+#define POLARSSL_ERR_ECP_MALLOC_FAILED                     -0x4D80  /**< Memory allocation failed. */
+#define POLARSSL_ERR_ECP_RANDOM_FAILED                     -0x4D00  /**< Generation of random value, such as (ephemeral) key, failed. */
+#define POLARSSL_ERR_ECP_INVALID_KEY                       -0x4C80  /**< Invalid private or public key. */
 
 #ifdef __cplusplus
 extern "C" {
@@ -301,7 +303,7 @@
  * \param ilen      Actual length of input
  *
  * \return          0 if successful,
- *                  POLARSSL_ERR_ECP_GENERIC if input is invalid
+ *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid
  *                  POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
  *
  * \note            This function does NOT check that the point actually
@@ -474,7 +476,7 @@
  * \param pt        Point to check
  *
  * \return          0 if point is a valid public key,
- *                  POLARSSL_ERR_ECP_GENERIC otherwise.
+ *                  POLARSSL_ERR_ECP_INVALID_KEY otherwise.
  *
  * \note            This function only checks the point is non-zero, has valid
  *                  coordinates and lies on the curve, but not that it is
@@ -497,7 +499,7 @@
  * \param d         Integer to check
  *
  * \return          0 if point is a valid private key,
- *                  POLARSSL_ERR_ECP_GENERIC otherwise.
+ *                  POLARSSL_ERR_ECP_INVALID_KEY otherwise.
  *
  * \note            Uses bare components rather than an ecp_keypair structure
  *                  in order to ease use with other structures such as
diff --git a/include/polarssl/error.h b/include/polarssl/error.h
index 0c9e451..bc3fb11 100644
--- a/include/polarssl/error.h
+++ b/include/polarssl/error.h
@@ -81,7 +81,7 @@
  * DHM       3   9
  * PKCS5     3   4 (Started from top)
  * RSA       4   9
- * ECP       4   4 (Started from top)
+ * ECP       4   7 (Started from top)
  * MD        5   4
  * CIPHER    6   5
  * SSL       6   6 (Started from top)
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 3484a74..8d0b2b5 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -77,7 +77,7 @@
 
             if( key_tries++ > 10 )
             {
-                ret = POLARSSL_ERR_ECP_GENERIC;
+                ret = POLARSSL_ERR_ECP_RANDOM_FAILED;
                 goto cleanup;
             }
         }
@@ -99,7 +99,7 @@
 
         if( sign_tries++ > 10 )
         {
-            ret = POLARSSL_ERR_ECP_GENERIC;
+            ret = POLARSSL_ERR_ECP_RANDOM_FAILED;
             goto cleanup;
         }
     }
diff --git a/library/ecp.c b/library/ecp.c
index fef9ab6..d8469c0 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -417,7 +417,7 @@
         return( mpi_mod_mpi( N, N, &grp->P ) );
 
     if( mpi_cmp_int( N, 0 ) < 0 || mpi_msb( N ) > 2 * grp->pbits )
-        return( POLARSSL_ERR_ECP_GENERIC );
+        return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
 
     MPI_CHK( grp->modp( N ) );
 
@@ -869,7 +869,7 @@
         return( ecp_normalize( grp, T ) );
 
     if( ( c = (mpi *) polarssl_malloc( t_len * sizeof( mpi ) ) ) == NULL )
-        return( POLARSSL_ERR_ECP_GENERIC );
+        return( POLARSSL_ERR_ECP_MALLOC_FAILED );
 
     mpi_init( &u ); mpi_init( &Zi ); mpi_init( &ZZi );
     for( i = 0; i < t_len; i++ )
@@ -1033,7 +1033,7 @@
      * Make sure Q coordinates are normalized
      */
     if( mpi_cmp_int( &Q->Z, 1 ) != 0 )
-        return( POLARSSL_ERR_ECP_GENERIC );
+        return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
 
     mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 ); mpi_init( &T4 );
     mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
@@ -1176,10 +1176,10 @@
     }
 
     /*
-     * We should have consumed all the bits now
+     * We should have consumed all bits, unless the input value was too big
      */
     if( mpi_cmp_int( &M, 0 ) != 0 )
-        ret = POLARSSL_ERR_ECP_GENERIC;
+        ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA;
 
 cleanup:
 
@@ -1245,7 +1245,7 @@
             mpi_shift_r( &l, 1 );
 
         if( count++ > 10 )
-            return( POLARSSL_ERR_ECP_GENERIC );
+            return( POLARSSL_ERR_ECP_RANDOM_FAILED );
     }
     while( mpi_cmp_int( &l, 1 ) <= 0 );
 
@@ -1406,19 +1406,19 @@
     mpi YY, RHS;
 
     if( mpi_cmp_int( &pt->Z, 0 ) == 0 )
-        return( POLARSSL_ERR_ECP_GENERIC );
+        return( POLARSSL_ERR_ECP_INVALID_KEY );
 
     /*
      * pt coordinates must be normalized for our checks
      */
     if( mpi_cmp_int( &pt->Z, 1 ) != 0 )
-        return( POLARSSL_ERR_ECP_GENERIC );
+        return( POLARSSL_ERR_ECP_INVALID_KEY );
 
     if( mpi_cmp_int( &pt->X, 0 ) < 0 ||
         mpi_cmp_int( &pt->Y, 0 ) < 0 ||
         mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 ||
         mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 )
-        return( POLARSSL_ERR_ECP_GENERIC );
+        return( POLARSSL_ERR_ECP_INVALID_KEY );
 
     mpi_init( &YY ); mpi_init( &RHS );
 
@@ -1433,7 +1433,7 @@
     MPI_CHK( mpi_add_mpi( &RHS, &RHS,    &grp->B  ) );  MOD_ADD( RHS );
 
     if( mpi_cmp_mpi( &YY, &RHS ) != 0 )
-        ret = POLARSSL_ERR_ECP_GENERIC;
+        ret = POLARSSL_ERR_ECP_INVALID_KEY;
 
 cleanup:
 
@@ -1449,7 +1449,7 @@
 {
     /* We want 1 <= d <= N-1 */
     if ( mpi_cmp_int( d, 1 ) < 0 || mpi_cmp_mpi( d, &grp->N ) >= 0 )
-        return( POLARSSL_ERR_ECP_GENERIC );
+        return( POLARSSL_ERR_ECP_INVALID_KEY );
 
     return( 0 );
 }
@@ -1475,7 +1475,7 @@
             mpi_shift_r( d, 1 );
 
         if( count++ > 10 )
-            return( POLARSSL_ERR_ECP_GENERIC );
+            return( POLARSSL_ERR_ECP_RANDOM_FAILED );
     }
     while( mpi_cmp_int( d, 1 ) < 0 );
 
diff --git a/library/error.c b/library/error.c
index 4323e72..04ce28e 100644
--- a/library/error.c
+++ b/library/error.c
@@ -215,12 +215,16 @@
             snprintf( buf, buflen, "ECP - Bad input parameters to function" );
         if( use_ret == -(POLARSSL_ERR_ECP_BUFFER_TOO_SMALL) )
             snprintf( buf, buflen, "ECP - The buffer is too small to write to" );
-        if( use_ret == -(POLARSSL_ERR_ECP_GENERIC) )
-            snprintf( buf, buflen, "ECP - Generic ECP error" );
         if( use_ret == -(POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE) )
             snprintf( buf, buflen, "ECP - Requested curve not available" );
         if( use_ret == -(POLARSSL_ERR_ECP_VERIFY_FAILED) )
             snprintf( buf, buflen, "ECP - The signature is not valid" );
+        if( use_ret == -(POLARSSL_ERR_ECP_MALLOC_FAILED) )
+            snprintf( buf, buflen, "ECP - Memory allocation failed" );
+        if( use_ret == -(POLARSSL_ERR_ECP_RANDOM_FAILED) )
+            snprintf( buf, buflen, "ECP - Generation of random value, such as (ephemeral) key, failed" );
+        if( use_ret == -(POLARSSL_ERR_ECP_INVALID_KEY) )
+            snprintf( buf, buflen, "ECP - Invalid private or public key" );
 #endif /* POLARSSL_ECP_C */
 
 #if defined(POLARSSL_MD_C)
diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data
index 55a3453..8f32bdc 100644
--- a/tests/suites/test_suite_ecp.data
+++ b/tests/suites/test_suite_ecp.data
@@ -104,34 +104,34 @@
 ecp_small_mul:-1:0:0:0:POLARSSL_ERR_ECP_BAD_INPUT_DATA
 
 ECP small check pubkey #1
-ecp_small_check_pub:1:1:0:POLARSSL_ERR_ECP_GENERIC
+ecp_small_check_pub:1:1:0:POLARSSL_ERR_ECP_INVALID_KEY
 
 ECP small check pubkey #2
-ecp_small_check_pub:9:-1:1:POLARSSL_ERR_ECP_GENERIC
+ecp_small_check_pub:9:-1:1:POLARSSL_ERR_ECP_INVALID_KEY
 
 ECP small check pubkey #3
 ecp_small_check_pub:9:46:1:0
 
 ECP small check pubkey #4
-ecp_small_check_pub:13:47:1:POLARSSL_ERR_ECP_GENERIC
+ecp_small_check_pub:13:47:1:POLARSSL_ERR_ECP_INVALID_KEY
 
 ECP small check pubkey #5
 ecp_small_check_pub:13:0:1:0
 
 ECP small check pubkey #6
-ecp_small_check_pub:-1:10:1:POLARSSL_ERR_ECP_GENERIC
+ecp_small_check_pub:-1:10:1:POLARSSL_ERR_ECP_INVALID_KEY
 
 ECP small check pubkey #7
 ecp_small_check_pub:46:10:1:0
 
 ECP small check pubkey #8
-ecp_small_check_pub:47:2:1:POLARSSL_ERR_ECP_GENERIC
+ecp_small_check_pub:47:2:1:POLARSSL_ERR_ECP_INVALID_KEY
 
 ECP small check pubkey #9
 ecp_small_check_pub:0:2:1:0
 
 ECP small check pubkey #10
-ecp_small_check_pub:10:25:1:POLARSSL_ERR_ECP_GENERIC
+ecp_small_check_pub:10:25:1:POLARSSL_ERR_ECP_INVALID_KEY
 
 ECP write binary #0 (zero, bad format)
 depends_on:POLARSSL_ECP_DP_SECP192R1_ENABLED
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 5b1ab60..7201e74 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -478,10 +478,10 @@
     TEST_ASSERT( ecp_use_known_dp( &grp, id ) == 0 );
 
     TEST_ASSERT( mpi_lset( &d, 0 ) == 0 );
-    TEST_ASSERT( ecp_check_privkey( &grp, &d ) == POLARSSL_ERR_ECP_GENERIC );
+    TEST_ASSERT( ecp_check_privkey( &grp, &d ) == POLARSSL_ERR_ECP_INVALID_KEY );
 
     TEST_ASSERT( mpi_copy( &d, &grp.N ) == 0 );
-    TEST_ASSERT( ecp_check_privkey( &grp, &d ) == POLARSSL_ERR_ECP_GENERIC );
+    TEST_ASSERT( ecp_check_privkey( &grp, &d ) == POLARSSL_ERR_ECP_INVALID_KEY );
 
     ecp_group_free( &grp );
     mpi_free( &d );