Introduce muladd_restartable() and its sub-context
Only the administrative parts for now, not actually restartable so far.
diff --git a/library/ecp.c b/library/ecp.c
index 4e637d7..4933460 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -101,9 +101,10 @@
}
/*
- * Restart context type for interrupted operations
+ * Restart sub-context for ecp_mul_comb()
*/
-struct mbedtls_ecp_restart_mul {
+struct mbedtls_ecp_restart_mul
+{
mbedtls_ecp_point R; /* current intermediate result */
size_t i; /* current index in various loops, 0 outside */
mbedtls_ecp_point *T; /* table for precomputed points */
@@ -119,7 +120,7 @@
};
/*
- * Init restart_mul context
+ * Init restart_mul sub-context
*/
static void ecp_restart_mul_init( mbedtls_ecp_restart_mul_ctx *ctx )
{
@@ -127,7 +128,7 @@
}
/*
- * Free the components of a restart_mul context
+ * Free the components of a restart_mul sub-context
*/
static void ecp_restart_mul_free( mbedtls_ecp_restart_mul_ctx *ctx )
{
@@ -148,6 +149,33 @@
}
/*
+ * Restart context for ecp_muladd()
+ */
+struct mbedtls_ecp_restart_muladd
+{
+ int state; /* dummy for now */
+};
+
+/*
+ * Init restart_muladd sub-context
+ */
+static void ecp_restart_muladd_init( mbedtls_ecp_restart_muladd_ctx *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+}
+
+/*
+ * Free the components of a restart_muladd sub-context
+ */
+static void ecp_restart_muladd_free( mbedtls_ecp_restart_muladd_ctx *ctx )
+{
+ if( ctx == NULL )
+ return;
+
+ memset( ctx, 0, sizeof( *ctx ) );
+}
+
+/*
* Initialize a restart context
*/
void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx )
@@ -1868,9 +1896,9 @@
if( ret != 0 )
mbedtls_ecp_point_free( R );
- /* clear restart context when not in progress (done or error) */
+ /* clear our sub-context when not in progress (done or error) */
#if defined(MBEDTLS_ECP_EARLY_RETURN)
- if( rs_ctx != NULL && rs_ctx->rsm != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) {
+ if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) {
ecp_restart_mul_free( rs_ctx->rsm );
mbedtls_free( rs_ctx->rsm );
rs_ctx->rsm = NULL;
@@ -2248,12 +2276,17 @@
}
/*
- * Linear combination
+ * Restartable linear combination
* NOT constant-time
*/
-int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+#if !defined(MBEDTLS_ECP_EARLY_RETURN)
+static
+#endif
+int mbedtls_ecp_muladd_restartable(
+ mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
- const mbedtls_mpi *n, const mbedtls_ecp_point *Q )
+ const mbedtls_mpi *n, const mbedtls_ecp_point *Q,
+ mbedtls_ecp_restart_ctx *rs_ctx )
{
int ret;
mbedtls_ecp_point mP;
@@ -2261,9 +2294,29 @@
char is_grp_capable = 0;
#endif
+#if !defined(MBEDTLS_ECP_EARLY_RETURN)
+ (void) rs_ctx;
+#endif
+
if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS )
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#if defined(MBEDTLS_ECP_EARLY_RETURN)
+ /* reset ops count for this call if top-level */
+ if( rs_ctx != NULL && rs_ctx->depth++ == 0 )
+ rs_ctx->ops_done = 0;
+
+ /* set up our own sub-context if needed */
+ if( ecp_max_ops != 0 && rs_ctx != NULL && rs_ctx->ma == NULL )
+ {
+ rs_ctx->ma = mbedtls_calloc( 1, sizeof( mbedtls_ecp_restart_muladd_ctx ) );
+ if( rs_ctx->ma == NULL )
+ return( MBEDTLS_ERR_ECP_ALLOC_FAILED );
+
+ ecp_restart_muladd_init( rs_ctx->ma );
+ }
+#endif /* MBEDTLS_ECP_EARLY_RETURN */
+
mbedtls_ecp_point_init( &mP );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, &mP, m, P ) );
@@ -2290,9 +2343,32 @@
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
mbedtls_ecp_point_free( &mP );
+#if defined(MBEDTLS_ECP_EARLY_RETURN)
+ /* clear our sub-context when not in progress (done or error) */
+ if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) {
+ ecp_restart_muladd_free( rs_ctx->ma );
+ mbedtls_free( rs_ctx->ma );
+ rs_ctx->ma = NULL;
+ }
+
+
+ if( rs_ctx != NULL )
+ rs_ctx->depth--;
+#endif /* MBEDTLS_ECP_EARLY_RETURN */
+
return( ret );
}
+/*
+ * Linear combination
+ * NOT constant-time
+ */
+int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+ const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+ const mbedtls_mpi *n, const mbedtls_ecp_point *Q )
+{
+ return( mbedtls_ecp_muladd_restartable( grp, R, m, P, n, Q, NULL ) );
+}
#if defined(ECP_MONTGOMERY)
/*