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().
This commit is contained in:
Manuel Pégourié-Gonnard 2019-11-15 10:47:45 +01:00
parent 41ab8cb6cb
commit e714332563
2 changed files with 8 additions and 12 deletions

View File

@ -936,6 +936,11 @@ int EccPoint_mult_safer(uECC_word_t * result, const uECC_word_t * point,
if (curve != uECC_secp256r1()) if (curve != uECC_secp256r1())
return 0; 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 /* Regularize the bitcount for the private key so that attackers cannot use a
* side channel attack to learn the number of leading zeros. */ * side channel attack to learn the number of leading zeros. */
carry = regularize_k(scalar, tmp, s); 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); 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; r = 0;
goto clear_and_out; goto clear_and_out;
} }

View File

@ -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; wordcount_t num_bytes = curve->num_bytes;
int r; 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: */ /* Converting buffers to correct bit order: */
uECC_vli_bytesToNative(_private, uECC_vli_bytesToNative(_private,
private_key, private_key,
@ -176,13 +170,8 @@ int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
num_bytes); num_bytes);
r = EccPoint_mult_safer(_public, _public, _private, curve); r = EccPoint_mult_safer(_public, _public, _private, curve);
if (r == 0)
goto clear_and_out;
uECC_vli_nativeToBytes(secret, num_bytes, _public); uECC_vli_nativeToBytes(secret, num_bytes, _public);
r = !EccPoint_isZero(_public, curve);
clear_and_out:
/* erasing temporary buffer used to store secret: */ /* erasing temporary buffer used to store secret: */
mbedtls_platform_zeroize(_private, sizeof(_private)); mbedtls_platform_zeroize(_private, sizeof(_private));