OpenSSL doesn't provide ML-DSA or ML-KEM
PostQuantumConfig.EnablePostQuantum or an operation with a PQ part throws a CryptographicException with
this message, even though OpenSSL loaded:
The loaded OpenSSL 3.0.13 ('/usr/lib/x86_64-linux-gnu/libcrypto.so.3') does not provide ML-DSA-65. Use an OpenSSL 3 build whose providers include it; the default provider has ML-DSA and ML-KEM from OpenSSL 3.5 on.
Instead of ML-DSA-65, the message can name any ML-DSA or ML-KEM parameter set, or HKDF, ARGON2ID,
PBKDF2, AES-256-GCM, or CHACHA20-POLY1305.
Environment
All targets that use the OpenSSL provider: .NET Framework, .NET Core 3.1, and .NET 8 on Windows, Linux, and macOS. Blazor WebAssembly isn't affected, because it brings OpenSSL along as a WebAssembly module.
Cause
The library loads any libcrypto that has the OpenSSL 3 API. Which algorithms an installation provides
doesn't depend on the version number alone, but on the providers that OpenSSL loads. That's why the
library asks the loaded installation, algorithm by algorithm, whether it provides what's needed:
EnablePostQuantum(CryptoMode.Hybrid)andEnablePostQuantum(CryptoMode.PostQuantum)ask for ML-DSA-65 and ML-KEM-768, the default parameter sets, at startup. If either is missing, the method throws, andDefaultModekeeps its previous value.- Every operation asks for the algorithm it needs before it computes anything, for example ML-DSA-87 for a key with that parameter set, or Argon2id for a key backup.
The message appears in these cases:
| Case | How to recognize it |
|---|---|
| OpenSSL earlier than 3.5 | The message names a version from 3.0 to 3.4. The default provider offers ML-DSA and ML-KEM only starting with 3.5. On Linux, this is often the system's OpenSSL, for example 3.0 on Ubuntu 24.04. |
| OpenSSL earlier than 3.2, and Argon2id | The message names ARGON2ID and version 3.0 or 3.1. |
| A build without the algorithms | The version is 3.5 or later. The installation was built with no-ml-dsa or no-ml-kem. |
| A configuration without the default provider | The version is 3.5 or later. An OpenSSL configuration (OPENSSL_CONF, openssl.cnf) loads only providers that don't offer the algorithm. |
If the policy refuses a parameter set, such as ML-DSA-44 without an exemption, the library reports that first, even if OpenSSL doesn't provide the parameter set. That message is described in The policy refuses an operation.
Resolution
- Read the version and the path from the message. They identify the installation that the library actually loaded.
- If the version is earlier than 3.5, install OpenSSL 3.5 or later for the process architecture, and set
PostQuantumConfig.OpenSslPathto its folder that containslibcrypto, as described in Configure OpenSSL. If the version is 3.5 or later, use the command-line tool of the same installation to check which algorithms it provides:
openssl list -signature-algorithms openssl list -kem-algorithms
If
ML-DSA-65orML-KEM-768is missing there, check the OpenSSL configuration thatOPENSSL_CONFpoints to, and activate the default provider. If they're missing even without a configuration, the installation was built without these algorithms; use a different one.- Restart the process. The library loads OpenSSL once per process and remembers the answers.
To find out up front whether the loaded installation provides ML-DSA-65 and ML-KEM-768, without causing an
exception, check MLDsaKey.IsSupported and MLKemKey.IsSupported.