summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2022-03-15 15:55:07 +0000
committertb <>2022-03-15 15:55:07 +0000
commitf410b1028c3297ee74ff7a977cb3028a9eb0f7ab (patch)
tree7ba35348200cc498ecb45ebf9d49a13072a74ca4
parentbe286d25e9849e9545c65b752d299592f60e16e9 (diff)
downloadopenbsd-OPENBSD_6_9.tar.gz
openbsd-OPENBSD_6_9.tar.bz2
openbsd-OPENBSD_6_9.zip
Fix infinite loop in BN_mod_sqrt()OPENBSD_6_9
A bug in the implementation of the Tonelli-Shanks algorithm can lead to an infinite loop. This loop can be hit in various ways, in particular on decompressing an elliptic curve public key via EC_POINT_oct2point() - to do this, one must solve y^2 = x^3 + ax + b for y, given x. If a certificate uses explicit encoding for elliptic curve parameters, this operation needs to be done during certificate verification, leading to a DoS. In particular, everything dealing with untrusted certificates is affected, notably TLS servers explicitly configured to request client certificates (httpd, smtpd, various VPN implementations, ...). Ordinary TLS servers do not consume untrusted certificates. The problem is that we cannot assume that x^3 + ax + b is actually a square on untrusted input and neither can we assume that the modulus p is a prime. Ensuring that p is a prime is too expensive (it would likely itself lead to a DoS). To avoid the infinite loop, fix the logic to be more resilient and explicitly limit the number of iterations that can be done. The bug is such that the infinite loop can also be hit for primes = 3 (mod 4) but fortunately that case is optimized earlier. It's also worth noting that there is a size bound on the field size enforced via OPENSSL_ECC_MAX_FIELD_BITS (= 661), which help mitigate further DoS vectors in presence of this fix. Reported by Tavis Ormandy and David Benjamin, Google Patch based on the fixes by David Benjamin and Tomas Mraz, OpenSSL ok beck inoguchi This is errata/6.9/032_bignum.patch.sig
-rw-r--r--src/lib/libcrypto/bn/bn_sqrt.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/src/lib/libcrypto/bn/bn_sqrt.c b/src/lib/libcrypto/bn/bn_sqrt.c
index 8514f23a27..de4f351d02 100644
--- a/src/lib/libcrypto/bn/bn_sqrt.c
+++ b/src/lib/libcrypto/bn/bn_sqrt.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_sqrt.c,v 1.9 2017/01/29 17:49:22 beck Exp $ */ 1/* $OpenBSD: bn_sqrt.c,v 1.9.16.1 2022/03/15 15:55:07 tb Exp $ */
2/* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> 2/* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * and Bodo Moeller for the OpenSSL project. */ 3 * and Bodo Moeller for the OpenSSL project. */
4/* ==================================================================== 4/* ====================================================================
@@ -351,21 +351,22 @@ BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
351 goto vrfy; 351 goto vrfy;
352 } 352 }
353 353
354 354 /* Find the smallest i with 0 < i < e such that b^(2^i) = 1. */
355 /* find smallest i such that b^(2^i) = 1 */ 355 for (i = 1; i < e; i++) {
356 i = 1; 356 if (i == 1) {
357 if (!BN_mod_sqr(t, b, p, ctx)) 357 if (!BN_mod_sqr(t, b, p, ctx))
358 goto end; 358 goto end;
359 while (!BN_is_one(t)) { 359 } else {
360 i++; 360 if (!BN_mod_sqr(t, t, p, ctx))
361 if (i == e) { 361 goto end;
362 BNerror(BN_R_NOT_A_SQUARE);
363 goto end;
364 } 362 }
365 if (!BN_mod_mul(t, t, t, p, ctx)) 363 if (BN_is_one(t))
366 goto end; 364 break;
365 }
366 if (i >= e) {
367 BNerror(BN_R_NOT_A_SQUARE);
368 goto end;
367 } 369 }
368
369 370
370 /* t := y^2^(e - i - 1) */ 371 /* t := y^2^(e - i - 1) */
371 if (!BN_copy(t, y)) 372 if (!BN_copy(t, y))