summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2023-03-04 21:37:37 +0000
committertb <>2023-03-04 21:37:37 +0000
commit8a82cbb62d388a2c5f2cfe6add96806986ba1d67 (patch)
tree7e6dcc972785d6113ee7a5192dbc3534af739346 /src
parentf5af461be23ab6e7a4a998f974edf286d18cac7c (diff)
downloadopenbsd-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')
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_ossl.c16
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
258static ECDSA_SIG * 266static ECDSA_SIG *
259ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 267ecdsa_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;