Adapt function signatures to rs_ctx + ret
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 91c4448..e8fb627 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -1866,7 +1866,8 @@
  * Check the signature of a certificate by its parent
  */
 static int x509_crt_check_signature( const mbedtls_x509_crt *child,
-                                     mbedtls_x509_crt *parent )
+                                     mbedtls_x509_crt *parent,
+                                     mbedtls_x509_crt_restart_ctx *rs_ctx )
 {
     const mbedtls_md_info_t *md_info;
     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
@@ -1878,14 +1879,24 @@
         return( -1 );
     }
 
-    if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
-                child->sig_md, hash, mbedtls_md_get_size( md_info ),
-                child->sig.p, child->sig.len ) != 0 )
-    {
+    /* Skip expensive computation on obvious mismatch */
+    if( ! mbedtls_pk_can_do( &parent->pk, child->sig_pk ) )
         return( -1 );
-    }
 
-    return( 0 );
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && child->sig_pk == MBEDTLS_PK_ECDSA )
+    {
+        return( mbedtls_pk_verify_restartable( &parent->pk,
+                    child->sig_md, hash, mbedtls_md_get_size( md_info ),
+                    child->sig.p, child->sig.len, &rs_ctx->ecdsa ) );
+    }
+#else
+    (void) rs_ctx;
+#endif
+
+    return( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
+                child->sig_md, hash, mbedtls_md_get_size( md_info ),
+                child->sig.p, child->sig.len ) );
 }
 
 /*
@@ -1952,17 +1963,19 @@
  * rely on key identifier extensions). (This is one way users might choose to
  * handle key rollover, another relies on self-issued certs, see [SIRO].)
  */
-static mbedtls_x509_crt *x509_crt_find_parent_in( mbedtls_x509_crt *child,
-                                                  mbedtls_x509_crt *candidates,
-                                                  int *signature_is_good,
-                                                  int top,
-                                                  int path_cnt,
-                                                  int self_cnt )
+static int x509_crt_find_parent_in(
+                        mbedtls_x509_crt *child,
+                        mbedtls_x509_crt *candidates,
+                        mbedtls_x509_crt **r_parent,
+                        int *r_signature_is_good,
+                        int top,
+                        int path_cnt,
+                        int self_cnt,
+                        mbedtls_x509_crt_restart_ctx *rs_ctx )
 {
+    int ret;
     mbedtls_x509_crt *parent, *fallback_parent = NULL;
-    int fallback_sign_good = 0;
-
-    *signature_is_good = 0;
+    int signature_is_good = 0, fallback_sign_good = 0;
 
     for( parent = candidates; parent != NULL; parent = parent->next )
     {
@@ -1978,8 +1991,17 @@
         }
 
         /* Signature */
-        *signature_is_good = x509_crt_check_signature( child, parent ) == 0;
-        if( top && ! *signature_is_good )
+        ret = x509_crt_check_signature( child, parent, rs_ctx );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+        if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) {
+            // TODO: stave state
+            return( ret );
+        }
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+        signature_is_good = ret == 0;
+        if( top && ! signature_is_good )
             continue;
 
         /* optional time check */
@@ -1989,7 +2011,7 @@
             if( fallback_parent == NULL )
             {
                 fallback_parent = parent;
-                fallback_sign_good = *signature_is_good;
+                fallback_sign_good = signature_is_good;
             }
 
             continue;
@@ -1998,13 +2020,18 @@
         break;
     }
 
-    if( parent == NULL )
+    if( parent != NULL )
     {
-        parent = fallback_parent;
-        *signature_is_good = fallback_sign_good;
+        *r_parent = parent;
+        *r_signature_is_good = signature_is_good;
+    }
+    else
+    {
+        *r_parent = fallback_parent;
+        *r_signature_is_good = fallback_sign_good;
     }
 
-    return parent;
+    return( 0 );
 }
 
 /*
@@ -2013,27 +2040,48 @@
  * Searches in trusted CAs first, and return the first suitable parent found
  * (see find_parent_in() for definition of suitable).
  */
-static mbedtls_x509_crt *x509_crt_find_parent( mbedtls_x509_crt *child,
-                                               mbedtls_x509_crt *trust_ca,
-                                               int *parent_is_trusted,
-                                               int *signature_is_good,
-                                               int path_cnt,
-                                               int self_cnt )
+static int x509_crt_find_parent(
+                        mbedtls_x509_crt *child,
+                        mbedtls_x509_crt *trust_ca,
+                        mbedtls_x509_crt **parent,
+                        int *parent_is_trusted,
+                        int *signature_is_good,
+                        int path_cnt,
+                        int self_cnt,
+                        mbedtls_x509_crt_restart_ctx *rs_ctx )
 {
-    mbedtls_x509_crt *parent;
+    int ret;
 
     /* Look for a parent in trusted CAs */
     *parent_is_trusted = 1;
-    parent = x509_crt_find_parent_in( child, trust_ca, signature_is_good,
-                                      1, path_cnt, self_cnt );
+    ret = x509_crt_find_parent_in( child, trust_ca,
+                                   parent, signature_is_good,
+                                   1, path_cnt, self_cnt, rs_ctx );
 
-    if( parent != NULL )
-        return parent;
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) {
+        // TODO: stave state
+        return( ret );
+    }
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+    if( *parent != NULL )
+        return( 0 );
 
     /* Look for a parent upwards the chain */
     *parent_is_trusted = 0;
-    return( x509_crt_find_parent_in( child, child->next, signature_is_good,
-                                     0, path_cnt, self_cnt ) );
+    ret = x509_crt_find_parent_in( child, child->next,
+                                   parent, signature_is_good,
+                                   0, path_cnt, self_cnt, rs_ctx );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) {
+        // TODO: stave state
+        return( ret );
+    }
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+    return( 0 );
 }
 
 /*
@@ -2109,8 +2157,10 @@
                 mbedtls_x509_crl *ca_crl,
                 const mbedtls_x509_crt_profile *profile,
                 x509_crt_verify_chain_item ver_chain[X509_MAX_VERIFY_CHAIN_SIZE],
-                size_t *chain_len )
+                size_t *chain_len,
+                mbedtls_x509_crt_restart_ctx *rs_ctx )
 {
+    int ret;
     uint32_t *flags;
     mbedtls_x509_crt *child;
     mbedtls_x509_crt *parent;
@@ -2154,9 +2204,16 @@
         }
 
         /* Look for a parent in trusted CAs or up the chain */
-        parent = x509_crt_find_parent( child, trust_ca,
+        ret = x509_crt_find_parent( child, trust_ca, &parent,
                                        &parent_is_trusted, &signature_is_good,
-                                       *chain_len - 1, self_cnt );
+                                       *chain_len - 1, self_cnt, rs_ctx );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+        if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) {
+            // TODO: stave state
+            return( ret );
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+        }
 
         /* No parent? We're done here */
         if( parent == NULL )
@@ -2351,8 +2408,6 @@
     size_t chain_len;
     uint32_t *ee_flags = &ver_chain[0].flags;
 
-    (void) rs_ctx;
-
     *flags = 0;
     memset( ver_chain, 0, sizeof( ver_chain ) );
     chain_len = 0;
@@ -2378,7 +2433,15 @@
 
     /* Check the chain */
     ret = x509_crt_verify_chain( crt, trust_ca, ca_crl, profile,
-                                 ver_chain, &chain_len );
+                                 ver_chain, &chain_len, rs_ctx );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) {
+        // TODO: stave state
+        return( ret );
+    }
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
     if( ret != 0 )
         goto exit;