diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h index 346b3a848..922d5da6e 100644 --- a/include/polarssl/ecp.h +++ b/include/polarssl/ecp.h @@ -42,6 +42,25 @@ extern "C" { #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) * @@ -59,11 +78,6 @@ typedef struct } ecp_point; -/* - * RFC 4492 defines an enum NamedCurve with two-bytes values - */ -typedef uint16_t ecp_group_id; - /** * \brief ECP group structure * @@ -107,27 +121,6 @@ typedef struct } 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) */ @@ -311,7 +304,7 @@ int ecp_point_read_binary( const ecp_group *grp, ecp_point *P, * * \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. @@ -345,6 +338,26 @@ int ecp_tls_read_group( ecp_group *grp, const unsigned char **buf, size_t len ); int ecp_tls_write_group( const ecp_group *grp, size_t *olen, 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 * diff --git a/library/ecp.c b/library/ecp.c index a80ddac63..8efa1831c 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -655,9 +655,11 @@ int ecp_use_known_dp( ecp_group *grp, ecp_group_id id ) 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_use_known_dp( ecp_group *grp, ecp_group_id id ) */ 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 @@ int ecp_tls_read_group( ecp_group *grp, const unsigned char **buf, size_t len ) /* * 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_read_group( ecp_group *grp, const unsigned char **buf, size_t len ) 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 @@ int ecp_tls_write_group( const ecp_group *grp, size_t *olen, /* * 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 e855377ac..a899affca 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -241,23 +241,23 @@ static void ssl_write_supported_elliptic_curves_ext( ssl_context *ssl, #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 040196d74..bb8d3e9a1 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -503,6 +503,7 @@ static int ssl_parse_supported_elliptic_curves( ssl_context *ssl, { 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 @@ static int ssl_parse_supported_elliptic_curves( ssl_context *ssl, 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