From 2b6312b7d90cbcb97f3f53d92d124422af3cb60b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 6 Nov 2019 10:42:02 +0100 Subject: [PATCH] Harden return value of uECC_vli_equal() Previously it was returning 0 or 1, so flipping a single bit in the return value reversed its meaning. Now it's returning the diff itself. This is safe because in the two places it's used (signature verification and point validation), invalid values will have a large number of bits differing from the expected value, so diff will have a large Hamming weight. An alternative would be to return for example -!(diff == 0), but the comparison itself is prone to attacks (glitching the appropriate flag in the CPU flags register, or the conditional branch if the comparison uses one). So we'd need to protect the comparison, and it's simpler to just skip it and return diff itself. --- include/tinycrypt/ecc.h | 2 +- tinycrypt/ecc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/tinycrypt/ecc.h b/include/tinycrypt/ecc.h index 9a705c495..0d1d9ec98 100644 --- a/include/tinycrypt/ecc.h +++ b/include/tinycrypt/ecc.h @@ -422,7 +422,7 @@ uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left, * @param left IN -- left term in comparison * @param right IN -- right term in comparison * @param num_words IN -- number of words - * @return Returns 0 if left == right, 1 otherwise. + * @return Returns 0 if left == right, non-zero otherwise. */ uECC_word_t uECC_vli_equal(const uECC_word_t *left, const uECC_word_t *right); diff --git a/tinycrypt/ecc.c b/tinycrypt/ecc.c index d01c67617..92906fd76 100644 --- a/tinycrypt/ecc.c +++ b/tinycrypt/ecc.c @@ -185,7 +185,7 @@ uECC_word_t uECC_vli_equal(const uECC_word_t *left, const uECC_word_t *right) for (i = NUM_ECC_WORDS - 1; i >= 0; --i) { diff |= (left[i] ^ right[i]); } - return !(diff == 0); + return diff; } uECC_word_t cond_set(uECC_word_t p_true, uECC_word_t p_false, unsigned int cond)