diff options
author | tb <> | 2023-03-04 21:37:37 +0000 |
---|---|---|
committer | tb <> | 2023-03-04 21:37:37 +0000 |
commit | 8a82cbb62d388a2c5f2cfe6add96806986ba1d67 (patch) | |
tree | 7e6dcc972785d6113ee7a5192dbc3534af739346 /src/lib/libcrypto/ecdsa | |
parent | f5af461be23ab6e7a4a998f974edf286d18cac7c (diff) | |
download | openbsd-8a82cbb62d388a2c5f2cfe6add96806986ba1d67.tar.gz openbsd-8a82cbb62d388a2c5f2cfe6add96806986ba1d67.tar.bz2 openbsd-8a82cbb62d388a2c5f2cfe6add96806986ba1d67.zip |
Cap the number of iterations in ECDSA signing
ECDSA is essentially the same thing as DSA, except that it is slightly
less stupid. Signing specifies an infinite loop, which is only possible
with arbitrary ECDSA domain parameters. Fortunately, most use of ECDSA
in the wild is based on well-known groups, so it is known a priori that
the loop is not infinite. Still, infinite loops are bad. A retry is
unlikely, 32 retries have a probability of ~2^-8000. So it's pretty
safe to error out.
ok beck jsing
Diffstat (limited to 'src/lib/libcrypto/ecdsa')
-rw-r--r-- | src/lib/libcrypto/ecdsa/ecs_ossl.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/lib/libcrypto/ecdsa/ecs_ossl.c b/src/lib/libcrypto/ecdsa/ecs_ossl.c index eec757ef7c..6f45e173b8 100644 --- a/src/lib/libcrypto/ecdsa/ecs_ossl.c +++ b/src/lib/libcrypto/ecdsa/ecs_ossl.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ecs_ossl.c,v 1.26 2022/11/26 16:08:52 tb Exp $ */ | 1 | /* $OpenBSD: ecs_ossl.c,v 1.27 2023/03/04 21:37:37 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Written by Nils Larsch for the OpenSSL project | 3 | * Written by Nils Larsch for the OpenSSL project |
4 | */ | 4 | */ |
@@ -255,6 +255,14 @@ ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp | |||
255 | return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); | 255 | return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); |
256 | } | 256 | } |
257 | 257 | ||
258 | |||
259 | /* | ||
260 | * It is too expensive to check curve parameters on every sign operation. | ||
261 | * Instead, cap the number of retries. A single retry is very unlikely, so | ||
262 | * allowing 32 retries is amply enough. | ||
263 | */ | ||
264 | #define ECDSA_MAX_SIGN_ITERATIONS 32 | ||
265 | |||
258 | static ECDSA_SIG * | 266 | static ECDSA_SIG * |
259 | ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | 267 | ecdsa_do_sign(const unsigned char *dgst, int dgst_len, |
260 | const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) | 268 | const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) |
@@ -266,6 +274,7 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | |||
266 | const EC_GROUP *group; | 274 | const EC_GROUP *group; |
267 | ECDSA_SIG *ret; | 275 | ECDSA_SIG *ret; |
268 | ECDSA_DATA *ecdsa; | 276 | ECDSA_DATA *ecdsa; |
277 | int attempts = 0; | ||
269 | int ok = 0; | 278 | int ok = 0; |
270 | 279 | ||
271 | ecdsa = ecdsa_check(eckey); | 280 | ecdsa = ecdsa_check(eckey); |
@@ -380,6 +389,11 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | |||
380 | ECDSAerror(ECDSA_R_NEED_NEW_SETUP_VALUES); | 389 | ECDSAerror(ECDSA_R_NEED_NEW_SETUP_VALUES); |
381 | goto err; | 390 | goto err; |
382 | } | 391 | } |
392 | |||
393 | if (++attempts > ECDSA_MAX_SIGN_ITERATIONS) { | ||
394 | ECDSAerror(EC_R_WRONG_CURVE_PARAMETERS); | ||
395 | goto err; | ||
396 | } | ||
383 | } else | 397 | } else |
384 | /* s != 0 => we have a valid signature */ | 398 | /* s != 0 => we have a valid signature */ |
385 | break; | 399 | break; |