Return and propagate UECC_FAULT_DETECTED

This commit first changes the return convention of EccPoint_mult_safer() so
that it properly reports when faults are detected. Then all functions that
call it need to be changed to (1) follow the same return convention and (2)
properly propagate UECC_FAULT_DETECTED when it occurs.

Here's the reverse call graph from EccPoint_mult_safer() to the rest of the
library (where return values are translated to the MBEDTLS_ERR_ space) and test
functions (where expected return values are asserted explicitly).

EccPoint_mult_safer()
    EccPoint_compute_public_key()
        uECC_compute_public_key()
            pkparse.c
            tests/suites/test_suite_pkparse.function
        uECC_make_key_with_d()
        uECC_make_key()
            ssl_cli.c
            ssl_srv.c
            tests/suites/test_suite_pk.function
            tests/suites/test_suite_tinycrypt.function
    uECC_shared_secret()
        ssl_tls.c
        tests/suites/test_suite_tinycrypt.function
    uECC_sign_with_k()
        uECC_sign()
            pk.c
            tests/suites/test_suite_tinycrypt.function

Note: in uECC_sign_with_k() a test for uECC_vli_isZero(p) is suppressed
because it is redundant with a more thorough test (point validity) done at the
end of EccPoint_mult_safer(). This redundancy was introduced in a previous
commit but not noticed earlier.
diff --git a/include/tinycrypt/ecc.h b/include/tinycrypt/ecc.h
index b199589..ebd16d6 100644
--- a/include/tinycrypt/ecc.h
+++ b/include/tinycrypt/ecc.h
@@ -217,7 +217,7 @@
  * @param private_key IN -- The private key to compute the public key for
  * @param public_key OUT -- Will be filled in with the corresponding public key
  * @param curve
- * @return Returns 1 if key was computed successfully, 0 if an error occurred.
+ * @return UECC_SUCCESS or UECC_FAILURE or UECC_FAULT_DETECTED
  */
 int uECC_compute_public_key(const uint8_t *private_key,
 			    uint8_t *public_key);
@@ -228,6 +228,7 @@
  * @param result OUT -- public-key
  * @param private_key IN -- private-key
  * @param curve IN -- elliptic curve
+ * @return UECC_SUCCESS or UECC_FAILURE or UECC_FAULT_DETECTED
  */
 uECC_word_t EccPoint_compute_public_key(uECC_word_t *result,
 					uECC_word_t *private_key);
@@ -241,6 +242,7 @@
  * @param result OUT -- returns scalar*point
  * @param point IN -- elliptic curve point
  * @param scalar IN -- scalar
+ * @return UECC_SUCCESS or UECC_FAILURE or UECC_FAULT_DETECTED
  */
 int EccPoint_mult_safer(uECC_word_t * result, const uECC_word_t * point,
 			const uECC_word_t * scalar);
diff --git a/include/tinycrypt/ecc_dh.h b/include/tinycrypt/ecc_dh.h
index 61e4c52..f471349 100644
--- a/include/tinycrypt/ecc_dh.h
+++ b/include/tinycrypt/ecc_dh.h
@@ -83,8 +83,7 @@
 
 /**
  * @brief Create a public/private key pair.
- * @return returns TC_CRYPTO_SUCCESS (1) if the key pair was generated successfully
- *         returns TC_CRYPTO_FAIL (0) if error while generating key pair
+ * @return UECC_SUCCESS or UECC_FAILURE or UECC_FAULT_DETECTED
  *
  * @param p_public_key OUT -- Will be filled in with the public key. Must be at
  * least 2 * the curve size (in bytes) long. For curve secp256r1, p_public_key
@@ -114,8 +113,7 @@
 /**
  * @brief Compute a shared secret given your secret key and someone else's
  * public key.
- * @return returns TC_CRYPTO_SUCCESS (1) if the shared secret was computed successfully
- *         returns TC_CRYPTO_FAIL (0) otherwise
+ * @return UECC_SUCCESS or UECC_FAILURE or UECC_FAULT_DETECTED
  *
  * @param p_secret OUT -- Will be filled in with the shared secret value. Must be
  * the same size as the curve size (for curve secp256r1, secret must be 32 bytes
diff --git a/include/tinycrypt/ecc_dsa.h b/include/tinycrypt/ecc_dsa.h
index 5985c7f..259cf44 100644
--- a/include/tinycrypt/ecc_dsa.h
+++ b/include/tinycrypt/ecc_dsa.h
@@ -92,8 +92,7 @@
 
 /**
  * @brief Generate an ECDSA signature for a given hash value.
- * @return returns TC_CRYPTO_SUCCESS (1) if the signature generated successfully
- *         returns TC_CRYPTO_FAIL (0) if an error occurred.
+ * @return UECC_SUCCESS or UECC_FAILURE or UECC_FAULT_DETECTED
  *
  * @param p_private_key IN -- Your private key.
  * @param p_message_hash IN -- The hash of the message to sign.
diff --git a/library/pk.c b/library/pk.c
index fbe711d..dfdd4d1 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -723,8 +723,9 @@
      #define MAX_SECP256R1_ECDSA_SIG_LEN ( 3 + 2 * ( 3 + NUM_ECC_BYTES ) )
 
     ret = uECC_sign( keypair->private_key, hash, hash_len, sig );
-    /* TinyCrypt uses 0 to signal errors. */
-    if( ret == 0 )
+    if( ret == UECC_FAULT_DETECTED )
+        return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+    if( ret != UECC_SUCCESS )
         return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
 
     *sig_len = 2 * NUM_ECC_BYTES;
diff --git a/library/pkparse.c b/library/pkparse.c
index 6a2507a..3f20225 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -987,7 +987,9 @@
     {
         ret = uECC_compute_public_key( keypair->private_key,
                                        keypair->public_key );
-        if( ret == 0 )
+        if( ret == UECC_FAULT_DETECTED )
+            return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+        if( ret != UECC_SUCCESS )
             return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
     }
 
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 3a5671e..7c03b41 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -3568,7 +3568,6 @@
 
     {
         ((void) n);
-        ((void) ret);
 
         if( (size_t)( end - p ) < 2 * NUM_ECC_BYTES + 2 )
             return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
@@ -3576,10 +3575,11 @@
         *p++ = 2 * NUM_ECC_BYTES + 1;
         *p++ = 0x04; /* uncompressed point presentation */
 
-        if( !uECC_make_key( p, ssl->handshake->ecdh_privkey ) )
-        {
+        ret = uECC_make_key( p, ssl->handshake->ecdh_privkey );
+        if( ret == UECC_FAULT_DETECTED )
+            return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+        if( ret != UECC_SUCCESS )
             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-        }
         p += 2 * NUM_ECC_BYTES;
     }
     else
@@ -3717,7 +3717,6 @@
         {
 #if defined(MBEDTLS_USE_TINYCRYPT)
             ((void) n);
-            ((void) ret);
 
             if( (size_t)( end - p ) < 2 * NUM_ECC_BYTES + 2 )
                 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
@@ -3725,10 +3724,11 @@
             *p++ = 2 * NUM_ECC_BYTES + 1;
             *p++ = 0x04; /* uncompressed point presentation */
 
-            if( !uECC_make_key( p, ssl->handshake->ecdh_privkey ) )
-            {
+            ret = uECC_make_key( p, ssl->handshake->ecdh_privkey );
+            if( ret == UECC_FAULT_DETECTED )
+                return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+            if( ret != UECC_SUCCESS )
                 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-            }
             p += 2 * NUM_ECC_BYTES;
 #else /* MBEDTLS_USE_TINYCRYPT */
             /*
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 43ca2ca..1ef8f94 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -3410,6 +3410,7 @@
 
 #if defined(MBEDTLS_USE_TINYCRYPT)
         {
+            int ret;
             static const unsigned char ecdh_param_hdr[] = {
                 MBEDTLS_SSL_EC_TLS_NAMED_CURVE,
                 0  /* high bits of secp256r1 TLS ID  */,
@@ -3426,12 +3427,12 @@
                     ecdh_param_hdr, sizeof( ecdh_param_hdr ) );
             ssl->out_msglen += sizeof( ecdh_param_hdr );
 
-            if( !uECC_make_key( &ssl->out_msg[ ssl->out_msglen ],
-                                ssl->handshake->ecdh_privkey ) )
-            {
-                MBEDTLS_SSL_DEBUG_MSG( 1, ( "Key creation failed" ) );
-                return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-            }
+            ret = uECC_make_key( &ssl->out_msg[ ssl->out_msglen ],
+                                 ssl->handshake->ecdh_privkey );
+            if( ret == UECC_FAULT_DETECTED )
+                return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+            if( ret != UECC_SUCCESS )
+                return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
 
             ssl->out_msglen += 2*NUM_ECC_BYTES;
         }
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 2fc569c..c12af96 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1973,14 +1973,13 @@
         mbedtls_ssl_suite_get_key_exchange( ciphersuite_info )
         == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
     {
-        ((void) ret);
-
-        if( !uECC_shared_secret( ssl->handshake->ecdh_peerkey,
-                                 ssl->handshake->ecdh_privkey,
-                                 ssl->handshake->premaster ) )
-        {
+        ret = uECC_shared_secret( ssl->handshake->ecdh_peerkey,
+                                  ssl->handshake->ecdh_privkey,
+                                  ssl->handshake->premaster );
+        if( ret == UECC_FAULT_DETECTED )
+            return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+        if( ret != UECC_SUCCESS )
             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-        }
 
         ssl->handshake->pmslen = NUM_ECC_BYTES;
     }
@@ -2168,14 +2167,13 @@
         size_t zlen;
 
 #if defined(MBEDTLS_USE_TINYCRYPT)
-        ((void) ret);
-
-        if( !uECC_shared_secret( ssl->handshake->ecdh_peerkey,
-                                 ssl->handshake->ecdh_privkey,
-                                 p + 2 ) )
-        {
+        ret = uECC_shared_secret( ssl->handshake->ecdh_peerkey,
+                                  ssl->handshake->ecdh_privkey,
+                                  p + 2 );
+        if( ret == UECC_FAULT_DETECTED )
+            return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+        if( ret != UECC_SUCCESS )
             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
-        }
 
         zlen = NUM_ECC_BYTES;
 #else /* MBEDTLS_USE_TINYCRYPT */
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 94e10ba..61bf95c 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -36,7 +36,7 @@
 
         ret = uECC_make_key( mbedtls_pk_uecc( *pk )->public_key,
                              mbedtls_pk_uecc( *pk )->private_key );
-        if( ret == 0 )
+        if( ret != UECC_SUCCESS )
             return( -1 );
 
         return( 0 );
diff --git a/tests/suites/test_suite_pkparse.function b/tests/suites/test_suite_pkparse.function
index 5563d60..54fa7af 100644
--- a/tests/suites/test_suite_pkparse.function
+++ b/tests/suites/test_suite_pkparse.function
@@ -137,7 +137,7 @@
         uecckey = mbedtls_pk_uecc( ctx );
         TEST_ASSERT( uECC_valid_public_key( uecckey->public_key ) == 0 );
         TEST_ASSERT( uECC_compute_public_key( uecckey->private_key,
-                                              tmp_pubkey ) != 0 );
+                                              tmp_pubkey ) == UECC_SUCCESS );
         TEST_ASSERT( memcmp( tmp_pubkey, uecckey->public_key,
                             sizeof( tmp_pubkey ) ) == 0 );
 #endif /* MBEDTLS_USE_TINYCRYPT */
diff --git a/tests/suites/test_suite_tinycrypt.function b/tests/suites/test_suite_tinycrypt.function
index 3e41720..3247e05 100644
--- a/tests/suites/test_suite_tinycrypt.function
+++ b/tests/suites/test_suite_tinycrypt.function
@@ -23,13 +23,13 @@
 
     uECC_set_rng( &uecc_rng_wrapper );
 
-    TEST_ASSERT( uECC_make_key( public1, private1 ) != 0 );
+    TEST_ASSERT( uECC_make_key( public1, private1 ) == UECC_SUCCESS );
 
-    TEST_ASSERT( uECC_make_key( public2, private2 ) != 0 );
+    TEST_ASSERT( uECC_make_key( public2, private2 ) == UECC_SUCCESS );
 
-    TEST_ASSERT( uECC_shared_secret( public2, private1, secret1 ) != 0 );
+    TEST_ASSERT( uECC_shared_secret( public2, private1, secret1 ) == UECC_SUCCESS );
 
-    TEST_ASSERT( uECC_shared_secret( public1, private2, secret2 ) != 0 );
+    TEST_ASSERT( uECC_shared_secret( public1, private2, secret2 ) == UECC_SUCCESS );
 
     TEST_ASSERT( memcmp( secret1, secret2, sizeof( secret1 ) ) == 0 );
 }
@@ -47,9 +47,9 @@
 
     TEST_ASSERT( rnd_std_rand( NULL, hash, NUM_ECC_BYTES ) == 0 );
 
-    TEST_ASSERT( uECC_make_key( public, private ) != 0 );
+    TEST_ASSERT( uECC_make_key( public, private ) == UECC_SUCCESS );
 
-    TEST_ASSERT( uECC_sign( private, hash, sizeof( hash ), sig ) != 0 );
+    TEST_ASSERT( uECC_sign( private, hash, sizeof( hash ), sig ) == UECC_SUCCESS );
 
     TEST_ASSERT( uECC_verify( public, hash, sizeof( hash ), sig ) == UECC_SUCCESS );
 }
@@ -71,9 +71,9 @@
     memcpy( public2 + NUM_ECC_BYTES, yB_str->x, yB_str->len );
 
     // Compute shared secrets and compare to test vector secret
-    TEST_ASSERT( uECC_shared_secret( public2, private1->x, secret1 ) != 0 );
+    TEST_ASSERT( uECC_shared_secret( public2, private1->x, secret1 ) == UECC_SUCCESS );
 
-    TEST_ASSERT( uECC_shared_secret( public1, private2->x, secret2 ) != 0 );
+    TEST_ASSERT( uECC_shared_secret( public1, private2->x, secret2 ) == UECC_SUCCESS );
 
     TEST_ASSERT( memcmp( secret1, secret2, sizeof( secret1 ) ) == 0 );
     TEST_ASSERT( memcmp( secret1, z_str->x, sizeof( secret1 ) ) == 0 );
diff --git a/tinycrypt/ecc.c b/tinycrypt/ecc.c
index 381beff..261db77 100644
--- a/tinycrypt/ecc.c
+++ b/tinycrypt/ecc.c
@@ -1021,16 +1021,16 @@
 	wordcount_t num_words = NUM_ECC_WORDS;
 	uECC_word_t carry;
 	uECC_word_t *initial_Z = 0;
-	int r;
+	int r = UECC_FAULT_DETECTED;
 
 	/* Protect against faults modifying curve paremeters in flash */
 	if (uECC_check_curve_integrity() != 0) {
-		return 0;
+		return UECC_FAULT_DETECTED;
 	}
 
-	/* Protects against invalid curves attacks */
+	/* Protects against invalid curve attacks */
 	if (uECC_valid_point(point) != 0 ) {
-		return 0;
+		return UECC_FAILURE;
 	}
 
 	/* Regularize the bitcount for the private key so that attackers cannot use a
@@ -1041,7 +1041,7 @@
          * protect against side-channel attacks such as Template SPA */
 	if (g_rng_function) {
 		if (!uECC_generate_random_int(k2[carry], curve_p, num_words)) {
-			r = 0;
+			r = UECC_FAILURE;
 			goto clear_and_out;
 		}
 		initial_Z = k2[carry];
@@ -1052,17 +1052,17 @@
 	/* Protect against fault injections that would make the resulting
 	 * point not lie on the intended curve */
 	if (uECC_valid_point(result) != 0 ) {
-		r = 0;
+		r = UECC_FAULT_DETECTED;
 		goto clear_and_out;
 	}
 
 	/* Protect against faults modifying curve paremeters in flash */
 	if (uECC_check_curve_integrity() != 0) {
-		r = 0;
+		r = UECC_FAULT_DETECTED;
 		goto clear_and_out;
 	}
 
-	r = 1;
+	r = UECC_SUCCESS;
 
 clear_and_out:
 	/* erasing temporary buffer used to store secret: */
@@ -1176,7 +1176,7 @@
 
 int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key)
 {
-
+	int ret;
 	uECC_word_t _private[NUM_ECC_WORDS];
 	uECC_word_t _public[NUM_ECC_WORDS * 2];
 
@@ -1187,23 +1187,24 @@
 
 	/* Make sure the private key is in the range [1, n-1]. */
 	if (uECC_vli_isZero(_private)) {
-		return 0;
+		return UECC_FAILURE;
 	}
 
 	if (uECC_vli_cmp(curve_n, _private) != 1) {
-		return 0;
+		return UECC_FAILURE;
 	}
 
 	/* Compute public key. */
-	if (!EccPoint_compute_public_key(_public, _private)) {
-		return 0;
+	ret = EccPoint_compute_public_key(_public, _private);
+	if (ret != UECC_SUCCESS) {
+		return ret;
 	}
 
 	uECC_vli_nativeToBytes(public_key, NUM_ECC_BYTES, _public);
 	uECC_vli_nativeToBytes(
 	public_key +
 	NUM_ECC_BYTES, NUM_ECC_BYTES, _public + NUM_ECC_WORDS);
-	return 1;
+	return UECC_SUCCESS;
 }
 #else
 typedef int mbedtls_dummy_tinycrypt_def;
diff --git a/tinycrypt/ecc_dh.c b/tinycrypt/ecc_dh.c
index 9fe03ca..3070ecf 100644
--- a/tinycrypt/ecc_dh.c
+++ b/tinycrypt/ecc_dh.c
@@ -75,7 +75,7 @@
 int uECC_make_key_with_d(uint8_t *public_key, uint8_t *private_key,
 			 unsigned int *d)
 {
-
+	int ret;
 	uECC_word_t _private[NUM_ECC_WORDS];
 	uECC_word_t _public[NUM_ECC_WORDS * 2];
 
@@ -85,30 +85,32 @@
 	mbedtls_platform_memcpy (_private, d, NUM_ECC_BYTES);
 
 	/* Computing public-key from private: */
-	if (EccPoint_compute_public_key(_public, _private)) {
-
-		/* Converting buffers to correct bit order: */
-		uECC_vli_nativeToBytes(private_key,
-				       BITS_TO_BYTES(NUM_ECC_BITS),
-				       _private);
-		uECC_vli_nativeToBytes(public_key,
-				       NUM_ECC_BYTES,
-				       _public);
-		uECC_vli_nativeToBytes(public_key + NUM_ECC_BYTES,
-				       NUM_ECC_BYTES,
-				       _public + NUM_ECC_WORDS);
-
-		/* erasing temporary buffer used to store secret: */
-		mbedtls_platform_memset(_private, 0, NUM_ECC_BYTES);
-
-		return 1;
+	ret = EccPoint_compute_public_key(_public, _private);
+	if (ret != UECC_SUCCESS) {
+		goto exit;
 	}
-	return 0;
+
+	/* Converting buffers to correct bit order: */
+	uECC_vli_nativeToBytes(private_key,
+			       BITS_TO_BYTES(NUM_ECC_BITS),
+			       _private);
+	uECC_vli_nativeToBytes(public_key,
+			       NUM_ECC_BYTES,
+			       _public);
+	uECC_vli_nativeToBytes(public_key + NUM_ECC_BYTES,
+			       NUM_ECC_BYTES,
+			       _public + NUM_ECC_WORDS);
+
+exit:
+	/* erasing temporary buffer used to store secret: */
+	mbedtls_platform_memset(_private, 0, NUM_ECC_BYTES);
+
+	return ret;
 }
 
 int uECC_make_key(uint8_t *public_key, uint8_t *private_key)
 {
-
+	int ret;
 	uECC_word_t _random[NUM_ECC_WORDS * 2];
 	uECC_word_t _private[NUM_ECC_WORDS];
 	uECC_word_t _public[NUM_ECC_WORDS * 2];
@@ -119,14 +121,19 @@
 		uECC_RNG_Function rng_function = uECC_get_rng();
 		if (!rng_function ||
 			!rng_function((uint8_t *)_random, 2 * NUM_ECC_WORDS*uECC_WORD_SIZE)) {
-        		return 0;
+        		return UECC_FAILURE;
 		}
 
 		/* computing modular reduction of _random (see FIPS 186.4 B.4.1): */
 		uECC_vli_mmod(_private, _random, curve_n);
 
 		/* Computing public-key from private: */
-		if (EccPoint_compute_public_key(_public, _private)) {
+		ret = EccPoint_compute_public_key(_public, _private);
+		/* don't try again if a fault was detected */
+		if (ret == UECC_FAULT_DETECTED) {
+			return ret;
+		}
+		if (ret == UECC_SUCCESS) {
 
 			/* Converting buffers to correct bit order: */
 			uECC_vli_nativeToBytes(private_key,
@@ -142,10 +149,10 @@
 			/* erasing temporary buffer that stored secret: */
 			mbedtls_platform_memset(_private, 0, NUM_ECC_BYTES);
 
-      			return 1;
+      			return UECC_SUCCESS;
     		}
   	}
-	return 0;
+	return UECC_FAILURE;
 }
 
 int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
diff --git a/tinycrypt/ecc_dsa.c b/tinycrypt/ecc_dsa.c
index 0d6683b..9ed6941 100644
--- a/tinycrypt/ecc_dsa.c
+++ b/tinycrypt/ecc_dsa.c
@@ -122,12 +122,12 @@
 	/* Make sure 0 < k < curve_n */
   	if (uECC_vli_isZero(k) ||
 	    uECC_vli_cmp(curve_n, k) != 1) {
-		return 0;
+		return UECC_FAILURE;
 	}
 
 	r = EccPoint_mult_safer(p, curve_G, k);
-	if (r == 0 || uECC_vli_isZero(p)) {
-		return 0;
+        if (r != UECC_SUCCESS) {
+		return r;
 	}
 
 	/* If an RNG function was specified, get a random number
@@ -137,7 +137,7 @@
 		tmp[0] = 1;
 	}
 	else if (!uECC_generate_random_int(tmp, curve_n, num_n_words)) {
-		return 0;
+		return UECC_FAILURE;
 	}
 
 	/* Prevent side channel analysis of uECC_vli_modInv() to determine
@@ -159,16 +159,17 @@
 	uECC_vli_modAdd(s, tmp, s, curve_n); /* s = e + r*d */
 	uECC_vli_modMult(s, s, k, curve_n);  /* s = (e + r*d) / k */
 	if (uECC_vli_numBits(s) > (bitcount_t)NUM_ECC_BYTES * 8) {
-		return 0;
+		return UECC_FAILURE;
 	}
 
 	uECC_vli_nativeToBytes(signature + NUM_ECC_BYTES, NUM_ECC_BYTES, s);
-	return 1;
+	return UECC_SUCCESS;
 }
 
 int uECC_sign(const uint8_t *private_key, const uint8_t *message_hash,
 	      unsigned hash_size, uint8_t *signature)
 {
+	int r;
 	      uECC_word_t _random[2*NUM_ECC_WORDS];
 	      uECC_word_t k[NUM_ECC_WORDS];
 	      uECC_word_t tries;
@@ -178,17 +179,23 @@
 		uECC_RNG_Function rng_function = uECC_get_rng();
 		if (!rng_function ||
 		    !rng_function((uint8_t *)_random, 2*NUM_ECC_WORDS*uECC_WORD_SIZE)) {
-			return 0;
+			return UECC_FAILURE;
 		}
 
 		// computing k as modular reduction of _random (see FIPS 186.4 B.5.1):
 		uECC_vli_mmod(k, _random, curve_n);
 
-		if (uECC_sign_with_k(private_key, message_hash, hash_size, k, signature)) {
-			return 1;
+		r = uECC_sign_with_k(private_key, message_hash, hash_size, k, signature);
+		/* don't keep trying if a fault was detected */
+		if (r == UECC_FAULT_DETECTED) {
+			return r;
 		}
+		if (r == UECC_SUCCESS) {
+			return UECC_SUCCESS;
+		}
+		/* else keep trying */
 	}
-	return 0;
+	return UECC_FAILURE;
 }
 
 static bitcount_t smax(bitcount_t a, bitcount_t b)