From e714332563449c86ad140328c145ccf27120011e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 15 Nov 2019 10:47:45 +0100 Subject: [PATCH] Add pre and post-validation to mult_safer() Validating the input is always a good idea. Validating the output protects against some fault injections that would make the result invalid. Note: valid_point() implies that the point is not zero. Adding validation to mult_safer() makes it redundant in compute_shared_secret(). --- tinycrypt/ecc.c | 9 ++++++++- tinycrypt/ecc_dh.c | 11 ----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/tinycrypt/ecc.c b/tinycrypt/ecc.c index c69d42278..b48083222 100644 --- a/tinycrypt/ecc.c +++ b/tinycrypt/ecc.c @@ -936,6 +936,11 @@ int EccPoint_mult_safer(uECC_word_t * result, const uECC_word_t * point, if (curve != uECC_secp256r1()) return 0; + /* Protects against invalid curves attacks */ + if (uECC_valid_point(point, curve) != 0 ) { + return 0; + } + /* Regularize the bitcount for the private key so that attackers cannot use a * side channel attack to learn the number of leading zeros. */ carry = regularize_k(scalar, tmp, s); @@ -952,7 +957,9 @@ int EccPoint_mult_safer(uECC_word_t * result, const uECC_word_t * point, EccPoint_mult(result, point, k2[!carry], initial_Z); - if (EccPoint_isZero(result, curve)) { + /* Protect against fault injections that would make the resulting + * point not lie on the intended curve */ + if (uECC_valid_point(result, curve) != 0 ) { r = 0; goto clear_and_out; } diff --git a/tinycrypt/ecc_dh.c b/tinycrypt/ecc_dh.c index f9c0a5ed1..e2f5655d6 100644 --- a/tinycrypt/ecc_dh.c +++ b/tinycrypt/ecc_dh.c @@ -158,12 +158,6 @@ int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key, wordcount_t num_bytes = curve->num_bytes; int r; - /* Protect against invalid curve attacks */ - if (uECC_valid_public_key(public_key, curve) != 0) { - r = 0; - goto clear_and_out; - } - /* Converting buffers to correct bit order: */ uECC_vli_bytesToNative(_private, private_key, @@ -176,13 +170,8 @@ int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key, num_bytes); r = EccPoint_mult_safer(_public, _public, _private, curve); - if (r == 0) - goto clear_and_out; - uECC_vli_nativeToBytes(secret, num_bytes, _public); - r = !EccPoint_isZero(_public, curve); -clear_and_out: /* erasing temporary buffer used to store secret: */ mbedtls_platform_zeroize(_private, sizeof(_private));