diff options
author | tb <> | 2022-04-07 17:38:24 +0000 |
---|---|---|
committer | tb <> | 2022-04-07 17:38:24 +0000 |
commit | 10c8b1e1311f7202e9ed7b622cad6d85557a5357 (patch) | |
tree | 6445ee7c9e643e6ae12636e212c627d4934e3f58 | |
parent | 8d808b1fad425472f16e190aa9c72037b7efe75a (diff) | |
download | openbsd-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.c | 27 |
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 | ||