Move ops count to top-level context

When a restartable function calls another restartable function, the current
ops_count needs to be shared to avoid either doing too many operations or
returning IN_PROGRESS uselessly. So it needs to be in the top-level context
rather than a specific sub-context.
This commit is contained in:
Manuel Pégourié-Gonnard 2017-04-20 10:03:45 +02:00
parent 8467e6848d
commit 646393bb1e
2 changed files with 10 additions and 8 deletions

View File

@ -184,7 +184,8 @@ typedef struct mbedtls_ecp_restart_mul mbedtls_ecp_restart_mul_ctx;
*/ */
typedef struct typedef struct
{ {
mbedtls_ecp_restart_mul_ctx *rsm; /*!< restart context for ecp_mul() */ unsigned ops_done; /*!< current ops count */
mbedtls_ecp_restart_mul_ctx *rsm; /*!< ecp_mul_comb() sub-context */
} mbedtls_ecp_restart_ctx; } mbedtls_ecp_restart_ctx;
#endif /* MBEDTLS_ECP_EARLY_RETURN */ #endif /* MBEDTLS_ECP_EARLY_RETURN */

View File

@ -104,7 +104,6 @@ void mbedtls_ecp_set_max_ops( unsigned max_ops )
* Restart context type for interrupted operations * Restart context type for interrupted operations
*/ */
struct mbedtls_ecp_restart_mul { struct mbedtls_ecp_restart_mul {
unsigned ops_done; /* number of operations done this time */
mbedtls_ecp_point R; /* current intermediate result */ mbedtls_ecp_point R; /* current intermediate result */
size_t i; /* current index in various loops, 0 outside */ size_t i; /* current index in various loops, 0 outside */
mbedtls_ecp_point *T; /* table for precomputed points */ mbedtls_ecp_point *T; /* table for precomputed points */
@ -164,6 +163,8 @@ void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx )
if( ctx == NULL ) if( ctx == NULL )
return; return;
ctx->ops_done = 0;
ecp_restart_mul_free( ctx->rsm ); ecp_restart_mul_free( ctx->rsm );
mbedtls_free( ctx->rsm ); mbedtls_free( ctx->rsm );
ctx->rsm = NULL; ctx->rsm = NULL;
@ -183,7 +184,7 @@ static int ecp_check_budget( const mbedtls_ecp_group *grp,
mbedtls_ecp_restart_ctx *rs_ctx, mbedtls_ecp_restart_ctx *rs_ctx,
unsigned ops ) unsigned ops )
{ {
if( rs_ctx != NULL && rs_ctx->rsm != NULL ) if( rs_ctx != NULL && ecp_max_ops != 0 )
{ {
/* scale depending on curve size: the chosen reference is 256-bit, /* scale depending on curve size: the chosen reference is 256-bit,
* and multiplication is quadratic. Round to the closest integer. */ * and multiplication is quadratic. Round to the closest integer. */
@ -193,11 +194,11 @@ static int ecp_check_budget( const mbedtls_ecp_group *grp,
ops *= 2; ops *= 2;
/* avoid infinite loops: always allow first step */ /* avoid infinite loops: always allow first step */
if( rs_ctx->rsm->ops_done != 0 && rs_ctx->rsm->ops_done + ops > ecp_max_ops ) if( rs_ctx->ops_done != 0 && rs_ctx->ops_done + ops > ecp_max_ops )
return( MBEDTLS_ERR_ECP_IN_PROGRESS ); return( MBEDTLS_ERR_ECP_IN_PROGRESS );
/* update running count */ /* update running count */
rs_ctx->rsm->ops_done += ops; rs_ctx->ops_done += ops;
} }
return( 0 ); return( 0 );
@ -1759,7 +1760,7 @@ static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
#endif #endif
#if defined(MBEDTLS_ECP_EARLY_RETURN) #if defined(MBEDTLS_ECP_EARLY_RETURN)
/* set up restart context if needed */ /* set up our own sub-context if needed */
if( ecp_max_ops != 0 && rs_ctx != NULL && rs_ctx->rsm == NULL ) if( ecp_max_ops != 0 && rs_ctx != NULL && rs_ctx->rsm == NULL )
{ {
rs_ctx->rsm = mbedtls_calloc( 1, sizeof( mbedtls_ecp_restart_mul_ctx ) ); rs_ctx->rsm = mbedtls_calloc( 1, sizeof( mbedtls_ecp_restart_mul_ctx ) );
@ -1770,8 +1771,8 @@ static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
} }
/* reset ops count for this call */ /* reset ops count for this call */
if( rs_ctx != NULL && rs_ctx->rsm != NULL ) if( rs_ctx != NULL )
rs_ctx->rsm->ops_done = 0; rs_ctx->ops_done = 0;
#endif #endif
/* Is P the base point ? */ /* Is P the base point ? */