Consistently reject large p and large q in DH

When applications use Diffie-Hellman incorrectly, and use
attacker-supplied domain parameters, rather than known-valid ones (as
required by SP 800-56A, 5.5.2), algorithms that aren't designed with
attacker-supplied parameters in mind become attack surfaces.

CVE-2023-3446 and CVE-2023-3817 in OpenSSL cover problems with the
DH_check function given large p and large q. This CL adds some fast
validity checks to the DH parameters before running any operation. This
differs from upstream in a few ways:

- Upstream only addressed issues with DH_check. We also check in
  DH_generate_key and DH_check_pub_key.

- For a more consistent invariant, reuse the existing DH modulus limit.
  Ideally we'd enforce these invariants on DH creation, but this is not
  possible due to OpenSSL's API. We additionally check some other
  cheap invariants.

This does not impact TLS, or any applications that used Diffie-Hellman
correctly, with trusted, well-known domain parameters.

Ultimately, that this comes up at all is a flaw in how DH was specified.
This is analogous to the issues with ECC with arbitrary groups and DSA,
which led to https://github.com/openssl/openssl/issues/20268
CVE-2022-0778, CVE-2020-0601, and likely others. Cryptographic
primitives should be limited to a small set of named, well-known domain
parameters.

Update-Note: Egregiously large or invalid DH p, q, or g values will be
more consistently rejected in DH operations. This does not impact TLS.
Applications should switch to modern primitives such as X25519 or ECDH
with P-256.

Change-Id: I666fe0b9f8b71632f6cf8064c8ea0251e5c286bb
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/62226
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
8 files changed
tree: 5e73ef35eef3c1826222395c6286249ca85e2417
  1. .github/
  2. cmake/
  3. crypto/
  4. decrepit/
  5. fuzz/
  6. include/
  7. pki/
  8. rust/
  9. ssl/
  10. third_party/
  11. tool/
  12. util/
  13. .clang-format
  14. .gitignore
  15. API-CONVENTIONS.md
  16. BREAKING-CHANGES.md
  17. BUILDING.md
  18. CMakeLists.txt
  19. codereview.settings
  20. CONTRIBUTING.md
  21. FUZZING.md
  22. go.mod
  23. go.sum
  24. INCORPORATING.md
  25. LICENSE
  26. PORTING.md
  27. README.md
  28. SANDBOXING.md
  29. sources.cmake
  30. STYLE.md
README.md

BoringSSL

BoringSSL is a fork of OpenSSL that is designed to meet Google's needs.

Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing so is likely to be frustrating because there are no guarantees of API or ABI stability.

Programs ship their own copies of BoringSSL when they use it and we update everything as needed when deciding to make API changes. This allows us to mostly avoid compromises in the name of compatibility. It works for us, but it may not work for you.

BoringSSL arose because Google used OpenSSL for many years in various ways and, over time, built up a large number of patches that were maintained while tracking upstream OpenSSL. As Google's product portfolio became more complex, more copies of OpenSSL sprung up and the effort involved in maintaining all these patches in multiple places was growing steadily.

Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's not part of the NDK) and a number of other apps/programs.

Project links:

There are other files in this directory which might be helpful: