Declare ecdsa_read_signature_restartable()

Not making ecdsa_verify_restartable() public, as it isn't called from any
other module.
diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h
index 259948d..f09e754 100644
--- a/include/mbedtls/ecdsa.h
+++ b/include/mbedtls/ecdsa.h
@@ -46,14 +46,31 @@
 /** Maximum size of an ECDSA signature in bytes */
 #define MBEDTLS_ECDSA_MAX_LEN  ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) )
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * \brief           ECDSA context structure
  */
 typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+
+/**
+ * \brief           General context for resuming ECDSA operations
+ */
+typedef struct
+{
+    mbedtls_ecp_restart_ctx rs_ecp;     /*!<  base context (admin+ecp info) */
+} mbedtls_ecdsa_restart_ctx;
+
+#else /* MBEDTLS_ECP_RESTARTABLE */
+
+/* Now we can declare functions that take a pointer to that */
+typedef void mbedtls_ecdsa_restart_ctx;
+
+#endif /* MBEDTLS_ECP_RESTARTABLE */
 
 /**
  * \brief           Compute ECDSA signature of a previously hashed message
@@ -228,6 +245,29 @@
                           const unsigned char *sig, size_t slen );
 
 /**
+ * \brief           Restartable version of \c mbedtls_ecdsa_read_signature()
+ *
+ * \note            Performs the same job as \c mbedtls_ecdsa_read_signature()
+ *                  but can return early and restart according to the limit
+ *                  set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
+ *
+ * \param ctx       ECDSA context
+ * \param hash      Message hash
+ * \param hlen      Size of hash
+ * \param sig       Signature to read and verify
+ * \param slen      Size of sig
+ * \param rs_ctx    Restart context
+ *
+ * \return          See \c mbedtls_ecdsa_read_signature(), or
+ *                  MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ */
+int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
+                          const unsigned char *hash, size_t hlen,
+                          const unsigned char *sig, size_t slen,
+                          mbedtls_ecdsa_restart_ctx *rs_ctx );
+
+/**
  * \brief           Generate an ECDSA keypair on the given curve
  *
  * \param ctx       ECDSA context in which the keypair should be stored
@@ -265,6 +305,18 @@
  */
 void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );
 
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+/**
+ * \brief           Initialize a restart context
+ */
+void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx );
+
+/**
+ * \brief           Free the components of a restart context
+ */
+void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 6873757..3003812 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -196,14 +196,18 @@
  * Verify ECDSA signature of hashed message (SEC1 4.1.4)
  * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
  */
-int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
-                  const unsigned char *buf, size_t blen,
-                  const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
+static int ecdsa_verify_restartable( mbedtls_ecp_group *grp,
+                                     const unsigned char *buf, size_t blen,
+                                     const mbedtls_ecp_point *Q,
+                                     const mbedtls_mpi *r, const mbedtls_mpi *s,
+                                     mbedtls_ecdsa_restart_ctx *rs_ctx )
 {
     int ret;
     mbedtls_mpi e, s_inv, u1, u2;
     mbedtls_ecp_point R;
 
+    (void) rs_ctx; // temporary
+
     mbedtls_ecp_point_init( &R );
     mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv );
     mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 );
@@ -278,6 +282,16 @@
 }
 
 /*
+ * Verify ECDSA signature of hashed message
+ */
+int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
+                  const unsigned char *buf, size_t blen,
+                  const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
+{
+    return( ecdsa_verify_restartable( grp, buf, blen, Q, r, s, NULL ) );
+}
+
+/*
  * Convert a signature (given by context) to ASN.1
  */
 static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
@@ -357,6 +371,18 @@
                           const unsigned char *hash, size_t hlen,
                           const unsigned char *sig, size_t slen )
 {
+    return( mbedtls_ecdsa_read_signature_restartable(
+                ctx, hash, hlen, sig, slen, NULL ) );
+}
+
+/*
+ * Restartable read and check signature
+ */
+int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
+                          const unsigned char *hash, size_t hlen,
+                          const unsigned char *sig, size_t slen,
+                          mbedtls_ecdsa_restart_ctx *rs_ctx )
+{
     int ret;
     unsigned char *p = (unsigned char *) sig;
     const unsigned char *end = sig + slen;
@@ -387,8 +413,8 @@
         goto cleanup;
     }
 
-    if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen,
-                              &ctx->Q, &r, &s ) ) != 0 )
+    if( ( ret = ecdsa_verify_restartable( &ctx->grp, hash, hlen,
+                              &ctx->Q, &r, &s, rs_ctx ) ) != 0 )
         goto cleanup;
 
     if( p != end )
@@ -444,4 +470,22 @@
     mbedtls_ecp_keypair_free( ctx );
 }
 
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+/*
+ * Initialize a restart context
+ */
+void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx )
+{
+    mbedtls_ecp_restart_init( &ctx->rs_ecp );
+}
+
+/*
+ * Free the components of a restart context
+ */
+void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx )
+{
+    mbedtls_ecp_restart_free( &ctx->rs_ecp );
+}
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
 #endif /* MBEDTLS_ECDSA_C */