Merge remote-tracking branch 'public/pr/2165' into development-proposed
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 9e6bb8a..425e3ea 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -108,6 +108,16 @@
 #error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_ECP_RESTARTABLE)           && \
+    ( defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \
+      defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)     || \
+      defined(MBEDTLS_ECDSA_SIGN_ALT)          || \
+      defined(MBEDTLS_ECDSA_VERIFY_ALT)        || \
+      defined(MBEDTLS_ECDSA_GENKEY_ALT)        || \
+      defined(MBEDTLS_ECP_ALT) )
+#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation"
+#endif
+
 #if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
 #error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
 #endif
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 28e860b..9f8192f 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -694,6 +694,10 @@
  * for too long on ECC (and, hence, X.509 or SSL/TLS) operations.
  *
  * Uncomment this macro to enable restartable ECC computations.
+ *
+ * \note  This option only works with the default software implementation of
+ *        elliptic curve functionality. It is incompatible with
+ *        MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT.
  */
 //#define MBEDTLS_ECP_RESTARTABLE
 
diff --git a/library/ecdh.c b/library/ecdh.c
index 80e9676..e6ae999 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -76,7 +76,7 @@
 {
     return( ecdh_gen_public_restartable( grp, d, Q, f_rng, p_rng, NULL ) );
 }
-#endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */
+#endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */
 
 #if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
 /*
@@ -110,7 +110,6 @@
 
     return( ret );
 }
-#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
 
 /*
  * Compute shared secret (SEC1 3.3.1)
@@ -123,6 +122,7 @@
     return( ecdh_compute_shared_restartable( grp, z, Q, d,
                                              f_rng, p_rng, NULL ) );
 }
+#endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
 
 /*
  * Initialize context
@@ -191,7 +191,9 @@
 {
     int ret;
     size_t grp_len, pt_len;
+#if defined(MBEDTLS_ECP_RESTARTABLE)
     mbedtls_ecp_restart_ctx *rs_ctx = NULL;
+#endif
 
     if( ctx == NULL || ctx->grp.pbits == 0 )
         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
@@ -201,9 +203,16 @@
         rs_ctx = &ctx->rs;
 #endif
 
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
     if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q,
                                              f_rng, p_rng, rs_ctx ) ) != 0 )
         return( ret );
+#else
+    if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
+                                         f_rng, p_rng ) ) != 0 )
+        return( ret );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
 
     if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) )
                 != 0 )
@@ -277,7 +286,9 @@
                       void *p_rng )
 {
     int ret;
+#if defined(MBEDTLS_ECP_RESTARTABLE)
     mbedtls_ecp_restart_ctx *rs_ctx = NULL;
+#endif
 
     if( ctx == NULL || ctx->grp.pbits == 0 )
         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
@@ -287,9 +298,15 @@
         rs_ctx = &ctx->rs;
 #endif
 
+#if defined(MBEDTLS_ECP_RESTARTABLE)
     if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q,
                     f_rng, p_rng, rs_ctx ) ) != 0 )
         return( ret );
+#else
+    if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
+                                         f_rng, p_rng ) ) != 0 )
+        return( ret );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
 
     return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
                                 olen, buf, blen );
@@ -325,7 +342,9 @@
                       void *p_rng )
 {
     int ret;
+#if defined(MBEDTLS_ECP_RESTARTABLE)
     mbedtls_ecp_restart_ctx *rs_ctx = NULL;
+#endif
 
     if( ctx == NULL || ctx->grp.pbits == 0 )
         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
@@ -335,11 +354,19 @@
         rs_ctx = &ctx->rs;
 #endif
 
+#if defined(MBEDTLS_ECP_RESTARTABLE)
     if( ( ret = ecdh_compute_shared_restartable( &ctx->grp,
                     &ctx->z, &ctx->Qp, &ctx->d, f_rng, p_rng, rs_ctx ) ) != 0 )
     {
         return( ret );
     }
+#else
+    if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp,
+                                             &ctx->d, f_rng, p_rng ) ) != 0 )
+    {
+        return( ret );
+    }
+#endif /* MBEDTLS_ECP_RESTARTABLE */
 
     if( mbedtls_mpi_size( &ctx->z ) > blen )
         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
diff --git a/library/ecdsa.c b/library/ecdsa.c
index abac015..a62c14c 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -369,7 +369,6 @@
 
     return( ret );
 }
-#endif /* MBEDTLS_ECDSA_SIGN_ALT */
 
 /*
  * Compute ECDSA signature of a hashed message
@@ -381,6 +380,7 @@
     return( ecdsa_sign_restartable( grp, r, s, d, buf, blen,
                                     f_rng, p_rng, NULL ) );
 }
+#endif /* !MBEDTLS_ECDSA_SIGN_ALT */
 
 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
 /*
@@ -432,8 +432,13 @@
 
 sign:
 #endif
+#if defined(MBEDTLS_ECDSA_SIGN_ALT)
+    ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen,
+                              mbedtls_hmac_drbg_random, p_rng );
+#else
     ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
                       mbedtls_hmac_drbg_random, p_rng, rs_ctx );
+#endif /* MBEDTLS_ECDSA_SIGN_ALT */
 
 cleanup:
     mbedtls_hmac_drbg_free( &rng_ctx );
@@ -564,7 +569,6 @@
 
     return( ret );
 }
-#endif /* MBEDTLS_ECDSA_VERIFY_ALT */
 
 /*
  * Verify ECDSA signature of hashed message
@@ -575,6 +579,7 @@
 {
     return( ecdsa_verify_restartable( grp, buf, blen, Q, r, s, NULL ) );
 }
+#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */
 
 /*
  * Convert a signature (given by context) to ASN.1
@@ -626,9 +631,14 @@
 #else
     (void) md_alg;
 
+#if defined(MBEDTLS_ECDSA_SIGN_ALT)
+    MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d,
+                         hash, hlen, f_rng, p_rng ) );
+#else
     MBEDTLS_MPI_CHK( ecdsa_sign_restartable( &ctx->grp, &r, &s, &ctx->d,
                          hash, hlen, f_rng, p_rng, rs_ctx ) );
-#endif
+#endif /* MBEDTLS_ECDSA_SIGN_ALT */
+#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
 
     MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) );
 
@@ -652,7 +662,7 @@
                 ctx, md_alg, hash, hlen, sig, slen, f_rng, p_rng, NULL ) );
 }
 
-#if ! defined(MBEDTLS_DEPRECATED_REMOVED) && \
+#if !defined(MBEDTLS_DEPRECATED_REMOVED) && \
     defined(MBEDTLS_ECDSA_DETERMINISTIC)
 int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
                                const unsigned char *hash, size_t hlen,
@@ -712,10 +722,15 @@
         ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
         goto cleanup;
     }
-
+#if defined(MBEDTLS_ECDSA_VERIFY_ALT)
+    if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen,
+                                      &ctx->Q, &r, &s ) ) != 0 )
+        goto cleanup;
+#else
     if( ( ret = ecdsa_verify_restartable( &ctx->grp, hash, hlen,
                               &ctx->Q, &r, &s, rs_ctx ) ) != 0 )
         goto cleanup;
+#endif /* MBEDTLS_ECDSA_VERIFY_ALT */
 
     /* At this point we know that the buffer starts with a valid signature.
      * Return 0 if the buffer just contains the signature, and a specific
@@ -740,7 +755,7 @@
     return( mbedtls_ecp_group_load( &ctx->grp, gid ) ||
             mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) );
 }
-#endif /* MBEDTLS_ECDSA_GENKEY_ALT */
+#endif /* !MBEDTLS_ECDSA_GENKEY_ALT */
 
 /*
  * Set context from an mbedtls_ecp_keypair