summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2023-03-04 20:54:52 +0000
committertb <>2023-03-04 20:54:52 +0000
commit98663aed9698c546fe7e0b3f24371011c019a59b (patch)
tree56d6ce1822f7f755194f5fbf467c6b748c4ec587
parent24d9ef03af8101abac25f58af7b7ec7bfa9050c9 (diff)
downloadopenbsd-98663aed9698c546fe7e0b3f24371011c019a59b.tar.gz
openbsd-98663aed9698c546fe7e0b3f24371011c019a59b.tar.bz2
openbsd-98663aed9698c546fe7e0b3f24371011c019a59b.zip
Provide dsa_check_key()
This is a cheap check that ensures basid parameter consistency per FIPS 186-4: 1 < g < q, that q has the allowed bit sizes 160, 224, 256 and that p is neither too small nor too large. Unfortunately, enforcing the three allowed sizes for p is not possible since the default dsa key generation has not respected this limitation. Instead of checking that p and q are prime, we only check that they are odd. Check that public and private keys, if set, are in the proper range. In particular, disallow zero values. Various versions of these checks have been added to the dsa code over time. This consolidates and extends them and in a subsequent commit wewill replace the incomplete checks. BoringSSL has a similar function of the same name, thanks to David Benjamin for pointing it out. ok beck jsing
-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