diff --git a/include/tinycrypt/ecc.h b/include/tinycrypt/ecc.h index b19958944..ebd16d6fe 100644 --- a/include/tinycrypt/ecc.h +++ b/include/tinycrypt/ecc.h @@ -217,7 +217,7 @@ int uECC_curve_public_key_size(void); * @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 @@ int uECC_compute_public_key(const uint8_t *private_key, * @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 @@ uECC_word_t EccPoint_compute_public_key(uECC_word_t *result, * @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 61e4c52ba..f471349e4 100644 --- a/include/tinycrypt/ecc_dh.h +++ b/include/tinycrypt/ecc_dh.h @@ -83,8 +83,7 @@ extern "C" { /** * @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 @@ int uECC_make_key_with_d(uint8_t *p_public_key, uint8_t *p_private_key, /** * @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 5985c7f0c..259cf44b3 100644 --- a/include/tinycrypt/ecc_dsa.h +++ b/include/tinycrypt/ecc_dsa.h @@ -92,8 +92,7 @@ extern "C" { /** * @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 fbe711dc2..dfdd4d143 100644 --- a/library/pk.c +++ b/library/pk.c @@ -723,8 +723,9 @@ static int uecc_eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, #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 6a2507aa3..3f202259f 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -987,7 +987,9 @@ static int pk_parse_key_sec1_der( mbedtls_uecc_keypair *keypair, { 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 3a5671e64..7c03b41f9 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -3568,7 +3568,6 @@ static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl, { ((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 @@ static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl, *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 @@ static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl, { #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 @@ static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl, *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 43ca2cac3..1ef8f9466 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -3410,6 +3410,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, #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 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, 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 2fc569c2f..c12af9684 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1973,14 +1973,13 @@ int mbedtls_ssl_build_pms( mbedtls_ssl_context *ssl ) 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 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch 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 94e10bab9..61bf95c0c 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -36,7 +36,7 @@ static int pk_genkey( mbedtls_pk_context *pk ) 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 5563d60bc..54fa7af90 100644 --- a/tests/suites/test_suite_pkparse.function +++ b/tests/suites/test_suite_pkparse.function @@ -137,7 +137,7 @@ void pk_parse_keyfile_ec( char * key_file, char * password, int result ) 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 3e41720ee..3247e054d 100644 --- a/tests/suites/test_suite_tinycrypt.function +++ b/tests/suites/test_suite_tinycrypt.function @@ -23,13 +23,13 @@ void test_ecdh() 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 @@ void test_ecdsa() 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 @@ void ecdh_primitive_testvec( data_t * private1, data_t * xA_str, 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 381beff54..261db77e0 100644 --- a/tinycrypt/ecc.c +++ b/tinycrypt/ecc.c @@ -1021,16 +1021,16 @@ int EccPoint_mult_safer(uECC_word_t * result, const uECC_word_t * point, 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 @@ int EccPoint_mult_safer(uECC_word_t * result, const uECC_word_t * point, * 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 @@ int EccPoint_mult_safer(uECC_word_t * result, const uECC_word_t * point, /* 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_valid_public_key(const uint8_t *public_key) 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 @@ int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key) /* 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 9fe03ca9a..3070ecf05 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 @@ int uECC_make_key_with_d(uint8_t *public_key, uint8_t *private_key, 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 @@ int uECC_make_key(uint8_t *public_key, uint8_t *private_key) 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 @@ int uECC_make_key(uint8_t *public_key, uint8_t *private_key) /* 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 0d6683be0..9ed6941ee 100644 --- a/tinycrypt/ecc_dsa.c +++ b/tinycrypt/ecc_dsa.c @@ -122,12 +122,12 @@ int uECC_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash, /* 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 @@ int uECC_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash, 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 @@ int uECC_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash, 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 @@ int uECC_sign(const uint8_t *private_key, const uint8_t *message_hash, 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)