Add function parsing a TLS ECParameters record
diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h
index b8b1997..6c14636 100644
--- a/include/polarssl/ecp.h
+++ b/include/polarssl/ecp.h
@@ -89,12 +89,14 @@
* \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.
*/
-#define POLARSSL_ECP_DP_SECP192R1 0
-#define POLARSSL_ECP_DP_SECP224R1 1
-#define POLARSSL_ECP_DP_SECP256R1 2
-#define POLARSSL_ECP_DP_SECP384R1 3
-#define POLARSSL_ECP_DP_SECP521R1 4
+#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 bit size of the groups (that is, of N)
@@ -120,6 +122,12 @@
#define POLARSSL_ECP_PF_UNCOMPRESSED 0 /**< Uncompressed point format */
#define POLARSSL_ECP_PF_COMPRESSED 1 /**< Compressed point format */
+/*
+ * Some constants from RFC 4492 (ECC for TLS)
+ */
+#define POLARSSL_ECP_TLS_NAMED_CURVE 3 /**< ECCurveType named_curve */
+
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -259,6 +267,7 @@
*/
int ecp_read_binary( const ecp_group *grp, ecp_point *P, int format,
const unsigned char *buf, size_t ilen );
+
/**
* \brief Set a group using well-known domain parameters
*
@@ -269,9 +278,23 @@
* POLARSSL_ERR_MPI_XXX if initialization failed
* POLARSSL_ERR_ECP_GENERIC if index is out of range
*
- * \note Index should be a POLARSSL_ECP_DP_XXX macro.
+ * \note Index should be a value of RFC 4492's enum NamdeCurve,
+ * possibly in the form of a POLARSSL_ECP_DP_XXX macro.
*/
-int ecp_use_known_dp( ecp_group *grp, size_t index );
+int ecp_use_known_dp( ecp_group *grp, uint16_t index );
+
+/**
+ * \brief Read a group from an ECParameters record
+ *
+ * \param grp Destination group
+ * \param buf Start of input buffer
+ * \param len Buffer length
+ *
+ * \return O if successful,
+ * POLARSSL_ERR_MPI_XXX if initialization failed
+ * POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid
+ */
+int ecp_tls_read_group( ecp_group *grp, const unsigned char *buf, size_t len );
/**
* \brief Addition: R = P + Q
diff --git a/library/ecp.c b/library/ecp.c
index b8b0dfc..0a27df2 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -29,6 +29,7 @@
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg
* GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
* FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
+ * RFC 4492 for the related TLS structures and constants
*/
#include "polarssl/config.h"
@@ -493,7 +494,7 @@
/*
* Set a group using well-known domain parameters
*/
-int ecp_use_known_dp( ecp_group *grp, size_t index )
+int ecp_use_known_dp( ecp_group *grp, uint16_t index )
{
switch( index )
{
@@ -525,7 +526,33 @@
SECP521R1_GX, SECP521R1_GY, SECP521R1_N ) );
}
- return( POLARSSL_ERR_ECP_GENERIC );
+ return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
+}
+
+/*
+ * Set a group from an ECParameters record (RFC 4492)
+ */
+int ecp_tls_read_group( ecp_group *grp, const unsigned char *buf, size_t len )
+{
+ uint16_t namedcurve;
+
+ /*
+ * We expect at least three bytes (see below)
+ */
+ if( len < 3 )
+ return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
+
+ /*
+ * First byte is curve_type; only named_curve is handled
+ */
+ if( *buf++ != POLARSSL_ECP_TLS_NAMED_CURVE )
+ return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
+
+ /*
+ * Next two bytes are the namedcurve
+ */
+ namedcurve = 256 * buf[0] + buf[1];
+ return ecp_use_known_dp( grp, namedcurve );
}
/*
diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data
index db04762..b875aac 100644
--- a/tests/suites/test_suite_ecp.data
+++ b/tests/suites/test_suite_ecp.data
@@ -184,6 +184,21 @@
ECP read binary #6 (non-zero, OK)
ecp_read_binary:SECP192R1:"0448d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc99336ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":UNCOMPRESSED:"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"6ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"01":0
+ECP read params #1 (record too short)
+ecp_read_params:"0313":POLARSSL_ERR_ECP_BAD_INPUT_DATA:0
+
+ECP read params #2 (bad curve_type)
+ecp_read_params:"010013":POLARSSL_ERR_ECP_BAD_INPUT_DATA:0
+
+ECP read params #3 (unknown curve)
+ecp_read_params:"030010":POLARSSL_ERR_ECP_BAD_INPUT_DATA:0
+
+ECP read params #4 (OK, buffer just fits)
+ecp_read_params:"030017":0:256
+
+ECP read params #5 (OK, buffer continues)
+ecp_read_params:"030018DEAD":0:384
+
ECP gen keypair
ecp_gen_keypair:SECP192R1
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 290b786..443d7a3 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -323,6 +323,28 @@
END_CASE
BEGIN_CASE
+ecp_read_params:record:ret:bits
+{
+ ecp_group grp;
+ unsigned char buf[10];
+ int len, ret;
+
+ ecp_group_init( &grp );
+ memset( buf, 0x00, sizeof( buf ) );
+
+ len = unhexify( buf, {record} );
+
+ ret = ecp_tls_read_group( &grp, buf, len );
+
+ TEST_ASSERT( ret == {ret} );
+ if( ret == 0)
+ TEST_ASSERT( mpi_msb( &grp.P ) == {bits} );
+
+ ecp_group_free( &grp );
+}
+END_CASE
+
+BEGIN_CASE
ecp_selftest:
{
TEST_ASSERT( ecp_self_test( 0 ) == 0 );