ECDH: Add mbedtls_ecdh_setup()

In the future we want to support alternative ECDH implementations. We
can't make assumptions about the structure of the context they might
use, and therefore shouldn't access the members of
`mbedtls_ecdh_context`.

Currently the lifecycle of the context can't be done without direct
manipulation. This commit adds `mbedtls_ecdh_setup()` to complete
covering the context lifecycle with functions.
This commit is contained in:
Janos Follath 2018-10-30 11:53:25 +00:00
parent 89ac8c9266
commit f61e486179
2 changed files with 49 additions and 8 deletions

View file

@ -134,6 +134,24 @@ int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
*/ */
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ); void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx );
/**
* \brief This function sets up the ECDH context with the information
* given.
*
* This function should be called after mbedtls_ecdh_init() but
* before mbedtls_ecdh_make_params(). There is no need to call
* this function before mbedtls_ecdh_read_params().
*
* This is the first function used by a TLS server for ECDHE
* ciphersuites.
*
* \param ctx The ECDH context to set up.
* \param grp_id The group id of the group to set up the context for.
*
* \return \c 0 on success.
*/
int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id );
/** /**
* \brief This function frees a context. * \brief This function frees a context.
* *
@ -145,8 +163,8 @@ void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
* \brief This function generates a public key and a TLS * \brief This function generates a public key and a TLS
* ServerKeyExchange payload. * ServerKeyExchange payload.
* *
* This is the first function used by a TLS server for ECDHE * This is the second function used by a TLS server for ECDHE
* ciphersuites. * ciphersuites. (It is called after mbedtls_ecdh_setup().)
* *
* \note This function assumes that the ECP group (grp) of the * \note This function assumes that the ECP group (grp) of the
* \p ctx context has already been properly set, * \p ctx context has already been properly set,
@ -242,8 +260,9 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
* \brief This function parses and processes a TLS ClientKeyExchange * \brief This function parses and processes a TLS ClientKeyExchange
* payload. * payload.
* *
* This is the second function used by a TLS server for ECDH(E) * This is the third function used by a TLS server for ECDH(E)
* ciphersuites. * ciphersuites. (It is called after mbedtls_ecdh_setup() and
* mbedtls_ecdh_make_params().)
* *
* \see ecp.h * \see ecp.h
* *

View file

@ -145,6 +145,23 @@ void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
#endif #endif
} }
/*
* Setup context
*/
int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id )
{
int ret;
ret = mbedtls_ecp_group_load( &ctx->grp, grp_id );
if( ret != 0 )
{
mbedtls_ecdh_free( ctx );
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
}
return( 0 );
}
/* /*
* Free context * Free context
*/ */
@ -240,12 +257,17 @@ int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
const unsigned char **buf, const unsigned char *end ) const unsigned char **buf, const unsigned char *end )
{ {
int ret; int ret;
mbedtls_ecp_group_id grp_id;
if( ( ret = mbedtls_ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 ) if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, end - *buf ) )
!= 0 )
return( ret ); return( ret );
if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) ) if( ( ret = mbedtls_ecdh_setup( ctx, grp_id ) ) != 0 )
!= 0 ) return( ret );
if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf,
end - *buf ) ) != 0 )
return( ret ); return( ret );
return( 0 ); return( 0 );
@ -259,7 +281,7 @@ int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypai
{ {
int ret; int ret;
if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ) if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 )
return( ret ); return( ret );
/* If it's not our key, just import the public part as Qp */ /* If it's not our key, just import the public part as Qp */