summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2022-04-07 17:38:24 +0000
committertb <>2022-04-07 17:38:24 +0000
commit10c8b1e1311f7202e9ed7b622cad6d85557a5357 (patch)
tree6445ee7c9e643e6ae12636e212c627d4934e3f58
parent8d808b1fad425472f16e190aa9c72037b7efe75a (diff)
downloadopenbsd-10c8b1e1311f7202e9ed7b622cad6d85557a5357.tar.gz
openbsd-10c8b1e1311f7202e9ed7b622cad6d85557a5357.tar.bz2
openbsd-10c8b1e1311f7202e9ed7b622cad6d85557a5357.zip
Avoid infinite loop on parsing DSA private keys
DSA private keys with ill-chosen g could cause an infinite loop on deserializing. Add a few sanity checks that ensure that g is according to the FIPS 186-4: check 1 < g < p and g^q == 1 (mod p). This is enough to ascertain that g is a generator of a multiplicative group of order q once we know that q is prime (which is checked a bit later). Issue reported with reproducers by Hanno Boeck. Additional variants and analysis by David Benjamin. ok beck jsing
-rw-r--r--src/lib/libcrypto/dsa/dsa_ameth.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/src/lib/libcrypto/dsa/dsa_ameth.c b/src/lib/libcrypto/dsa/dsa_ameth.c
index 07773ad44f..9b8f09d969 100644
--- a/src/lib/libcrypto/dsa/dsa_ameth.c
+++ b/src/lib/libcrypto/dsa/dsa_ameth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dsa_ameth.c,v 1.34 2022/02/24 21:07:03 tb Exp $ */ 1/* $OpenBSD: dsa_ameth.c,v 1.35 2022/04/07 17:38:24 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006. 3 * project 2006.
4 */ 4 */
@@ -479,7 +479,7 @@ old_dsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
479{ 479{
480 DSA *dsa; 480 DSA *dsa;
481 BN_CTX *ctx = NULL; 481 BN_CTX *ctx = NULL;
482 BIGNUM *j, *p1, *newp1; 482 BIGNUM *j, *p1, *newp1, *powg;
483 int qbits; 483 int qbits;
484 484
485 if (!(dsa = d2i_DSAPrivateKey(NULL, pder, derlen))) { 485 if (!(dsa = d2i_DSAPrivateKey(NULL, pder, derlen))) {
@@ -498,6 +498,13 @@ old_dsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
498 goto err; 498 goto err;
499 } 499 }
500 500
501 /* Check that 1 < g < p. */
502 if (BN_cmp(dsa->g, BN_value_one()) <= 0 ||
503 BN_cmp(dsa->g, dsa->p) >= 0) {
504 DSAerror(DSA_R_PARAMETER_ENCODING_ERROR); /* XXX */
505 goto err;
506 }
507
501 ctx = BN_CTX_new(); 508 ctx = BN_CTX_new();
502 if (ctx == NULL) 509 if (ctx == NULL)
503 goto err; 510 goto err;
@@ -509,7 +516,8 @@ old_dsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
509 j = BN_CTX_get(ctx); 516 j = BN_CTX_get(ctx);
510 p1 = BN_CTX_get(ctx); 517 p1 = BN_CTX_get(ctx);
511 newp1 = BN_CTX_get(ctx); 518 newp1 = BN_CTX_get(ctx);
512 if (j == NULL || p1 == NULL || newp1 == NULL) 519 powg = BN_CTX_get(ctx);
520 if (j == NULL || p1 == NULL || newp1 == NULL || powg == NULL)
513 goto err; 521 goto err;
514 /* p1 = p - 1 */ 522 /* p1 = p - 1 */
515 if (BN_sub(p1, dsa->p, BN_value_one()) == 0) 523 if (BN_sub(p1, dsa->p, BN_value_one()) == 0)
@@ -526,6 +534,19 @@ old_dsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
526 } 534 }
527 535
528 /* 536 /*
537 * Check that g generates a multiplicative subgroup of order q.
538 * We only check that g^q == 1, so the order is a divisor of q.
539 * Once we know that q is prime, this is enough.
540 */
541
542 if (!BN_mod_exp_ct(powg, dsa->g, dsa->q, dsa->p, ctx))
543 goto err;
544 if (BN_cmp(powg, BN_value_one()) != 0) {
545 DSAerror(DSA_R_PARAMETER_ENCODING_ERROR); /* XXX */
546 goto err;
547 }
548
549 /*
529 * Check that q is not a composite number. 550 * Check that q is not a composite number.
530 */ 551 */
531 552