summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/dsa/dsa_lib.c75
-rw-r--r--src/lib/libcrypto/dsa/dsa_local.h4
2 files changed, 77 insertions, 2 deletions
diff --git a/src/lib/libcrypto/dsa/dsa_lib.c b/src/lib/libcrypto/dsa/dsa_lib.c
index af8f33980a..38f0b071ec 100644
--- a/src/lib/libcrypto/dsa/dsa_lib.c
+++ b/src/lib/libcrypto/dsa/dsa_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dsa_lib.c,v 1.39 2022/11/26 16:08:52 tb Exp $ */ 1/* $OpenBSD: dsa_lib.c,v 1.40 2023/03/04 20:54:52 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -423,3 +423,76 @@ DSA_bits(const DSA *dsa)
423{ 423{
424 return BN_num_bits(dsa->p); 424 return BN_num_bits(dsa->p);
425} 425}
426
427int
428dsa_check_key(const DSA *dsa)
429{
430 int p_bits, q_bits;
431
432 if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
433 DSAerror(DSA_R_MISSING_PARAMETERS);
434 return 0;
435 }
436
437 /* Checking that p and q are primes is expensive. Check they are odd. */
438 if (!BN_is_odd(dsa->p) || !BN_is_odd(dsa->q)) {
439 DSAerror(DSA_R_INVALID_PARAMETERS);
440 return 0;
441 }
442
443 /* FIPS 186-4: 1 < g < p. */
444 if (BN_cmp(dsa->g, BN_value_one()) <= 0 ||
445 BN_cmp(dsa->g, dsa->p) >= 0) {
446 DSAerror(DSA_R_INVALID_PARAMETERS);
447 return 0;
448 }
449
450 /* We know p and g are positive. The next two checks imply q > 0. */
451 if (BN_is_negative(dsa->q)) {
452 DSAerror(DSA_R_BAD_Q_VALUE);
453 return 0;
454 }
455
456 /* FIPS 186-4 only allows three sizes for q. */
457 q_bits = BN_num_bits(dsa->q);
458 if (q_bits != 160 && q_bits != 224 && q_bits != 256) {
459 DSAerror(DSA_R_BAD_Q_VALUE);
460 return 0;
461 }
462
463 /*
464 * XXX - FIPS 186-4 only allows 1024, 2048, and 3072 bits for p.
465 * Cap the size to reduce DoS risks. Poor defaults make keys with
466 * incorrect p sizes >= 512 bits common, so only enforce a weak
467 * lower bound.
468 */
469 p_bits = BN_num_bits(dsa->p);
470 if (p_bits > OPENSSL_DSA_MAX_MODULUS_BITS) {
471 DSAerror(DSA_R_MODULUS_TOO_LARGE);
472 return 0;
473 }
474 if (p_bits < 512) {
475 DSAerror(DSA_R_INVALID_PARAMETERS);
476 return 0;
477 }
478
479 /* The public key must be in the multiplicative group (mod p). */
480 if (dsa->pub_key != NULL) {
481 if (BN_cmp(dsa->pub_key, BN_value_one()) <= 0 ||
482 BN_cmp(dsa->pub_key, dsa->p) >= 0) {
483 DSAerror(DSA_R_INVALID_PARAMETERS);
484 return 0;
485 }
486 }
487
488 /* The private key must be nonzero and in GF(q). */
489 if (dsa->priv_key != NULL) {
490 if (BN_cmp(dsa->priv_key, BN_value_one()) <= 0 ||
491 BN_cmp(dsa->priv_key, dsa->q) >= 0) {
492 DSAerror(DSA_R_INVALID_PARAMETERS);
493 return 0;
494 }
495 }
496
497 return 1;
498}
diff --git a/src/lib/libcrypto/dsa/dsa_local.h b/src/lib/libcrypto/dsa/dsa_local.h
index 0487bd9f41..a413db9747 100644
--- a/src/lib/libcrypto/dsa/dsa_local.h
+++ b/src/lib/libcrypto/dsa/dsa_local.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: dsa_local.h,v 1.1 2022/11/26 16:08:52 tb Exp $ */ 1/* $OpenBSD: dsa_local.h,v 1.2 2023/03/04 20:54:52 tb Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 2007 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -115,4 +115,6 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
115 unsigned char *seed_out, 115 unsigned char *seed_out,
116 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); 116 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
117 117
118int dsa_check_key(const DSA *dsa);
119
118__END_HIDDEN_DECLS 120__END_HIDDEN_DECLS