From 054433c4935709df80ea1cb0d01849b6c745d009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 22 Mar 2017 11:18:33 +0100 Subject: [PATCH] Add mbedtls_ecp_set_max_ops() The plan is to count basic operations as follows: - call to ecp_add_mixed() -> 11 - call to ecp_double_jac() -> 8 - call to mpi_mul_mpi() -> 1 - call to mpi_inv_mod() -> 120 - everything else -> not counted The counts for ecp_add_mixed() and ecp_double_jac() are based on the actual number of calls to mpi_mul_mpi() they they make. The count for mpi_inv_mod() is based on timing measurements on K64F and LPC1768 boards, and are consistent with the usual very rough estimate of one inversion = 100 multiplications. It could be useful to repeat that measurement on a Cortex-M0 board as those have smaller divider and multipliers, so the result could be a bit different but should be the same order of magnitude. The documented limitation of 120 basic ops is due to the calls to mpi_inv_mod() which are currently not interruptible nor planned to be so far. --- include/mbedtls/ecp.h | 34 +++++++++++++++++++++++++++++++++- library/ecp.c | 16 ++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index f821690ef..7bcc69c01 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -240,6 +240,33 @@ mbedtls_ecp_keypair; */ #define MBEDTLS_ECP_TLS_NAMED_CURVE 3 /**< ECCurveType's named_curve */ +#if defined(MBEDTLS_ECP_EARLY_RETURN) +/** + * \brief Set the maximum number of basic operations done in a row. + * + * If more operations are needed to complete a computation, + * MBEDTLS_ERR_ECP_IN_PROGRESS will be returned by the + * function performing the computation. That function will + * then need to be called again with the same arguments until + * it returns 0 or an other error code. + * + * \param max_ops Maximum number of basic operations done in a row. + * Default: 0 (unlimited). + * Lower (non-zero) values mean ECC functions will block for + * a lesser maximum amount of time. + * + * \note A "basic operation" is roughly multiplication in GF(p), + * or whatever takes a roughly equivalent amount of time. + * As an indication, a scalar multiplication on P-256 is + * of the order of 3600 "basic operations" with default + * settings. + * + * \warning Values lower than 120 are currently not well-supported, in + * that sometimes functions will have to block for longer. + */ +void mbedtls_ecp_set_max_ops( unsigned max_ops ); +#endif /* MBEDTLS_ECP_EARLY_RETURN */ + /** * \brief Get the list of supported curves in order of preferrence * (full information) @@ -525,7 +552,12 @@ int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen, * \return 0 if successful, * MBEDTLS_ERR_ECP_INVALID_KEY if m is not a valid privkey * or P is not a valid pubkey, - * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed + * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, + * MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached (see \c mbedtls_ecp_set_max_ops()), + * indicating the function should be called again with the + * exact same arguments. + * */ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, diff --git a/library/ecp.c b/library/ecp.c index c7f4b04bb..1358a3f8c 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -85,6 +85,22 @@ static void mbedtls_zeroize( void *v, size_t n ) { static unsigned long add_count, dbl_count, mul_count; #endif + +#if defined(MBEDTLS_ECP_EARLY_RETURN) +/* + * Maximum number of "basic operations" to be done in a row. + */ +static unsigned ecp_max_ops = 0; + +/* + * Set ecp_max_ops + */ +void mbedtls_ecp_set_max_ops( unsigned max_ops ) +{ + ecp_max_ops = max_ops; +} +#endif /* MBEDTLS_ECP_EARLY_RETURN */ + #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \