From 1a96728964ccbdd2ea831377e5e8eb71b08359dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Sat, 9 Feb 2013 17:03:58 +0100 Subject: [PATCH] Add function parsing a TLS ECParameters record --- include/polarssl/ecp.h | 37 ++++++++++++++++++++++------ library/ecp.c | 31 +++++++++++++++++++++-- tests/suites/test_suite_ecp.data | 15 +++++++++++ tests/suites/test_suite_ecp.function | 22 +++++++++++++++++ 4 files changed, 96 insertions(+), 9 deletions(-) diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h index b8b19978b..6c1463637 100644 --- a/include/polarssl/ecp.h +++ b/include/polarssl/ecp.h @@ -89,12 +89,14 @@ ecp_group; * \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 @@ ecp_group; #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_write_binary( const ecp_group *grp, const ecp_point *P, int format, */ 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 @@ int ecp_read_binary( const ecp_group *grp, ecp_point *P, int format, * 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 b8b0dfc74..0a27df2be 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 @@ cleanup: /* * 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 @@ int ecp_use_known_dp( ecp_group *grp, size_t index ) 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 db047629d..b875aac00 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -184,6 +184,21 @@ ecp_read_binary:SECP192R1:"0548d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc99336ce 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 290b786de..443d7a3d0 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -322,6 +322,28 @@ ecp_gen_keypair:id } 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: {