diff --git a/include/polarssl/ecdh.h b/include/polarssl/ecdh.h index 5c9be4595..ad131061c 100644 --- a/include/polarssl/ecdh.h +++ b/include/polarssl/ecdh.h @@ -33,9 +33,35 @@ extern "C" { #endif -#ifdef __cplusplus -} -#endif +/** + * \brief Generate a public key + * + * \param grp ECP group + * \param d Destination MPI (secret exponent) + * \param Q Destination point (public key) + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful, + * or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code + */ +int ecdh_gen_public( const ecp_group *grp, mpi *d, ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Compute shared secret + * + * \param grp ECP group + * \param z Destination MPI (shared secret) + * \param Q Public key from other party + * \param d Our secret exponent + * + * \return 0 if successful, + * or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code + */ +int ecdh_compute_shared( const ecp_group *grp, mpi *z, + const ecp_point *Q, const mpi *d ); /** * \brief Checkup routine @@ -44,4 +70,8 @@ extern "C" { */ int ecdh_self_test( int verbose ); +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h index e1b099540..b8b19978b 100644 --- a/include/polarssl/ecp.h +++ b/include/polarssl/ecp.h @@ -147,11 +147,22 @@ void ecp_group_free( ecp_group *grp ); /** * \brief Set a point to zero * + * \param pt Destination point + * * \return 0 if successful, * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed */ int ecp_set_zero( ecp_point *pt ); +/** + * \brief Tell if a point is zero + * + * \param pt Point to test + * + * \return 1 if point is zero, 0 otherwise + */ +int ecp_is_zero( ecp_point *pt ); + /** * \brief Copy the contents of point Q into P * diff --git a/library/ecdh.c b/library/ecdh.c index a706b2e29..15158990a 100644 --- a/library/ecdh.c +++ b/library/ecdh.c @@ -35,6 +35,45 @@ #include "polarssl/ecdh.h" +/* + * Generate public key: simple wrapper around ecp_gen_keypair + */ +int ecdh_gen_public( const ecp_group *grp, mpi *d, ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + return ecp_gen_keypair( grp, d, Q, f_rng, p_rng ); +} + +/* + * Compute shared secret (SEC1 3.3.1) + */ +int ecdh_compute_shared( const ecp_group *grp, mpi *z, + const ecp_point *Q, const mpi *d ) +{ + int ret; + ecp_point P; + + ecp_point_init( &P ); + + /* + * Make sure Q is a valid pubkey before using it + */ + MPI_CHK( ecp_check_pubkey( grp, Q ) ); + + MPI_CHK( ecp_mul( grp, &P, d, Q ) ); + + if( ecp_is_zero( &P ) ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + MPI_CHK( mpi_copy( z, &P.X ) ); + +cleanup: + ecp_point_free( &P ); + + return( ret ); +} + #if defined(POLARSSL_SELF_TEST) diff --git a/library/ecp.c b/library/ecp.c index 9153f11ad..b8b0dfc74 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -121,6 +121,14 @@ cleanup: return( ret ); } +/* + * Tell if a point is zero + */ +int ecp_is_zero( ecp_point *pt ) +{ + return( mpi_cmp_int( &pt->Z, 0 ) == 0 ); +} + /* * Copy the contents of Q into P */