Selecting ML-KEM (FIPS 203) or SLH-DSA (FIPS 205) as your post-quantum algorithm is the easy part. The harder decision is which library implements it correctly, in a form you can actually deploy. NIST published the final standards in August 2024. The library ecosystem has been updating since then, but not uniformly. Some libraries implement the final specification; some still carry pre-standardisation draft code with known interoperability breaks. Some hold FIPS 140-3 validation or have it in progress; many do not. This article maps the current state so you can make that selection on evidence rather than assumption.
For broader vendor evaluation beyond C and Rust implementations, see PQC Vendor Selection: Cryptographic Library Providers. For the KEM architecture context that drives library requirements, see Key Encapsulation Mechanisms for Security Architects.
Why the library choice is not automatic once the algorithm is chosen
Three criteria must be evaluated independently. Most engineers check one.
The first is FIPS 203 compliance, meaning the final August 2024 standard, not the CRYSTALS-Kyber Round 3 draft that preceded it. NIST FIPS 203 Section 1.3 documents the changes from the Kyber specification: the domain separation in the key generation and encapsulation functions was modified between the Round 3 submission and the final standard. CRYSTALS-Kyber Round 3 and FIPS 203 ML-KEM are not byte-compatible. A client using a Round 3 library cannot interoperate with a server using a FIPS 203 library for key exchange. FIPS-regulated deployments must use FIPS 203 implementations, not Round 3. The same break exists between SPHINCS+ and FIPS 205 SLH-DSA. Checking a library's CHANGELOG for "FIPS 203" or "ML-KEM final" is mandatory before committing to a library choice.
The second criterion is FIPS 140-3 validation status. A library that implements ML-KEM correctly is not the same thing as a FIPS 140-3 validated ML-KEM implementation. For US federal deployments, CMMC Level 2 and 3 requirements, and FedRAMP, FIPS 140-3 validated modules are a compliance requirement. The NIST CMVP (Cryptographic Module Validation Programme) database is the definitive source. A module's FIPS 140-3 certificate explicitly lists the validated algorithms in scope; a module being FIPS 140-3 validated does not automatically mean ML-KEM is within its validated scope if the certificate was issued before FIPS 203 finalisation.
The third criterion is production maturity: API stability, active security patch maintenance, platform support for the target environment, and a licensing model compatible with the application's distribution requirements.
liboqs: the reference platform and its limitations
liboqs (Open Quantum Safe C library) is an open-source C library maintained by the Open Quantum Safe project at the University of Waterloo. It implements all four NIST-standardised PQC algorithms: ML-KEM (FIPS 203), ML-DSA (FIPS 204), SLH-DSA (FIPS 205), and FN-DSA (FIPS 206). The API is uniform across all implemented algorithms: OQS_KEM_new(), OQS_KEM_keypair(), OQS_KEM_encaps(), OQS_KEM_decaps(). Algorithm selection is a string identifier passed at runtime (for example, "ML-KEM-768"), with function pointers for the algorithm-specific operations returned from OQS_KEM_new(). This design directly implements the crypto agility principle from NIST CSWP 04282021: algorithm selection happens at the configuration layer, not in application code.
liboqs is the integration point for OQS-OpenSSL (the OpenSSL integration fork), OQS-BoringSSL, OQS-curl, and language wrappers for Python, Java, Go, Rust, and others. As of knowledge cutoff August 2025, liboqs had been updated to implement the final FIPS 203 specification. Verify the liboqs CHANGELOG at publication date to confirm the specific release targets FIPS 203 (not Kyber Round 3); the test vector confirmation against FIPS 203 Table 1 key sizes is the definitive check.
The limitation is clear and must be stated plainly: liboqs does not hold FIPS 140-3 validation. The Open Quantum Safe project explicitly does not claim FIPS 140-3 validation in its documentation. liboqs is a research and integration reference library. It is appropriate for prototyping, testing, and building integration forks. For production deployments with FIPS 140-3 compliance requirements, liboqs is the reference, not the module. The OQS integration forks (OQS-OpenSSL, OQS-BoringSSL) may lag upstream security patches; production deployments should use mainline libraries where available.
For broader vendor evaluation context, see PQC Vendor Selection: Cryptographic Library Providers.
OpenSSL 3.5: mainline ML-KEM without the fork
OpenSSL 3.5 (released 2025) includes ML-KEM support in the mainline codebase, without requiring the OQS fork or any additional plugin. ML-KEM-512, ML-KEM-768, and ML-KEM-1024 are all supported as key encapsulation algorithms. OpenSSL 3.5 implements the final NIST FIPS 203 specification. This is the recommended library for server-side TLS on Linux, macOS, and Windows deployments where the application uses OpenSSL directly and FIPS 140-3 validation is not a hard requirement.
One clarification is essential: OpenSSL 3.5 as a library and the OpenSSL FIPS provider as a validated module are distinct things. The FIPS provider in OpenSSL is the FIPS 140-3 validated module; it is validated separately from the main library, on a different CMVP submission timeline. NIST CMVP validation for a new algorithm, including ML-KEM, takes months to years after the standard is published. The OpenSSL FIPS provider module validated before FIPS 203 finalisation will not have ML-KEM within its validated scope.
The verification step: check the NIST CMVP database for the OpenSSL FIPS provider module certificate and confirm that ML-KEM (FIPS 203) appears within the validated algorithm scope. Do not assume that "I am running OpenSSL 3.5" equals "I have FIPS 140-3 validated ML-KEM." Those are different statements and only the CMVP certificate confirms the second.
AWS-LC and BoringSSL: production-validated C libraries
AWS-LC (Amazon's fork of BoringSSL, also known as aws-lc or libcrypto-aws) is the cryptographic library underlying AWS services. It has integrated ML-KEM-768 and is used for hybrid TLS in AWS service endpoints. AWS-LC holds FIPS 140-3 validation for its cryptographic module (AWS-LC-FIPS), and FIPS 140-3 validation for the ML-KEM implementation within AWS-LC-FIPS was in progress as of knowledge cutoff August 2025. Verify the current CMVP certificate scope for the AWS-LC-FIPS module before treating it as a FIPS 140-3 validated ML-KEM implementation.
AWS-LC's production validation comes from a specific source: it is the library under AWS TLS termination infrastructure. The scale of that deployment provides real-world correctness assurance that no academic benchmark can match. AWS-LC is open source (Apache 2.0 licence) and available independently of AWS services. Its API follows BoringSSL conventions (EVP_PKEY-based interface), making it a workable drop-in for BoringSSL-based applications. For third-party production C deployments requiring both production maturity and a path to FIPS 140-3 validation, AWS-LC is the strongest current option.
BoringSSL (Google's fork of OpenSSL, used by Chrome, Android, and Google services) has supported X25519+ML-KEM-768 hybrid TLS since 2023. The Chrome deployment at internet scale provides the largest real-world validation of ML-KEM TLS implementation correctness available. However, BoringSSL has documented API stability limitations: it is not designed for third-party use, and Google's API guarantees are intentionally limited. BoringSSL also does not pursue FIPS 140-3 validation as part of its standard release; Google uses separate modules (Conscrypt for Android, BoringCrypto for Go) for FIPS contexts.
One assumption to verify at publication date: as of knowledge cutoff, BoringSSL may still have been in transition between the pre-standardisation Kyber768 and the final FIPS 203 ML-KEM-768. Google committed to updating BoringSSL to FIPS 203 after standardisation. Chrome's 2023 deployment performance data, cited in the companion article on ML-KEM vs X25519 performance, therefore covers the transition period and should not be read as exclusively reflecting the final FIPS 203 standard; the two implementations are not byte-compatible, as FIPS 203 Section 1.3 documents the domain separation changes from Round 3. Confirm the current BoringSSL CHANGELOG and test vector conformance before citing it as a FIPS 203 compliant implementation in any regulated context.
wolfSSL: embedded systems and FIPS-focused deployments
wolfSSL is a C cryptographic library designed for embedded systems, RTOS environments, and deployments where FIPS 140-3 compliance is a commercial requirement. wolfSSL holds FIPS 140-3 validation for its core cryptographic module and has been pursuing FIPS 140-3 validation for post-quantum algorithm additions following NIST FIPS finalisation. Verify the current CMVP certificate scope for the wolfSSL FIPS module; the same principle applies as with AWS-LC: a module being FIPS 140-3 validated does not mean ML-KEM is within scope unless the certificate says so.
wolfSSL's differentiation is its embedded platform support. For deployments on ARM Cortex-M class devices, RTOS environments, and hardware security modules with constrained memory, wolfSSL provides ML-KEM implementations tuned for low-memory operation with configurable stack and heap footprints. The PQM4 project benchmarks (Kannwischer et al., IACR ePrint 2019/844) show ML-KEM-768 key generation at approximately 1.9 ms on Cortex-M4 class hardware. Devices operating below this threshold require hardware replacement, but for devices that can run ML-KEM within latency budget, wolfSSL is the practical library choice in the FIPS-regulated embedded segment.
wolfSSL uses a dual-licence model: GPL for open-source projects and a commercial licence for proprietary products. Product vendors distributing software who cannot comply with GPL must evaluate the commercial licence terms. This is an operational criterion, not a technical one, but it affects library selection in commercial IoT and embedded product development.
Rust libraries: RustCrypto and aws-lc-rs
The Rust ecosystem provides FIPS 203 and 205 implementations via the RustCrypto organisation on GitHub. Three crates are directly relevant:
- ml-kem crate (crates.io): Pure-Rust implementation of NIST FIPS 203 ML-KEM. All three parameter sets (ML-KEM-512, ML-KEM-768, ML-KEM-1024) are implemented as separate type-safe structs: MlKem512, MlKem768, MlKem1024. The crate targets the final FIPS 203 specification. Verify the crate release notes and README at publication date for explicit FIPS 203 conformance confirmation and test vector references.
- slh-dsa crate (crates.io): Pure-Rust implementation of NIST FIPS 205 SLH-DSA. Multiple parameter sets supported.
- ml-dsa crate (crates.io): Pure-Rust implementation of NIST FIPS 204 ML-DSA.
The Rust ml-kem crate's type system enforces parameter set selection at compile time: passing an ML-KEM-768 key where ML-KEM-1024 is expected is a type error, not a runtime failure. The API makes illegal states unrepresentable. For new server-side applications and system services written in Rust, the RustCrypto crates are the natural starting point. They are pure-Rust implementations with no FFI to C code, which simplifies security auditing and eliminates C FFI safety issues from the threat model.
The constraint: RustCrypto crates do not hold FIPS 140-3 validation. For Rust applications in FIPS-regulated environments, two options exist. The practical path is the aws-lc-rs crate (crates.io), which provides a Rust-idiomatic API over the FIPS-validated AWS-LC C library via a minimal FFI boundary. aws-lc-rs brings AWS-LC's production maturity and FIPS 140-3 validation path to Rust applications at the cost of the C dependency. Verify the aws-lc-rs crate documentation and the corresponding CMVP certificate scope for ML-KEM at publication date. The second option is to await FIPS 140-3 validation of a Rust-native cryptographic library. This had not been achieved as of knowledge cutoff August 2025.
FIPS 140-3 validation: how to read the CMVP database
The CMVP validation process for a new algorithm is independent of the algorithm publication timeline. When NIST publishes FIPS 203, library vendors must submit an Implementation Under Test to NVLAP-accredited testing laboratories, which test the implementation against the FIPS 203 Known Answer Tests (KATs). NIST then reviews the results and issues a certificate. This process typically takes six to eighteen months. As of knowledge cutoff August 2025, some vendors had submitted ML-KEM implementations to CMVP, but validated certificates covering ML-KEM were not yet issued for the majority.
Three steps for verifying FIPS 140-3 validation status:
- Query the CMVP database at https://csrc.nist.gov/projects/cryptographic-module-validation-program. Search by vendor name or module name. Do not search by library version.
- Open the certificate and read the algorithm scope. Each certificate lists the validated algorithms explicitly. Confirm that "ML-KEM (FIPS 203)" appears, not "Kyber" (which would indicate a pre-standard implementation) and not just "KEM" as a generic category.
- Check the validation date against the FIPS 203 publication date (August 2024). A certificate issued before August 2024 cannot include FIPS 203 ML-KEM in its scope.
For organisations with active FIPS 140-3 compliance requirements, NIST's ACVTS (Automated Cryptographic Validation Testing System) provides an intermediate evidence source. Vendors can submit their ML-KEM implementation to ACVTS for testing against the FIPS 203 test vectors independently of a full FIPS 140-3 module submission. ACVTS test results confirm implementation correctness against the standard and precede full module validation. Some vendors publish their ACVTS results as evidence of FIPS 203 conformance while CMVP validation is pending. This is useful evidence during the transition period, but it is not equivalent to a FIPS 140-3 validated module for compliance purposes.
SLH-DSA (FIPS 205): specific implementation considerations
SLH-DSA is frequently underweighted in library roundups that focus on ML-KEM. It has a fundamentally different implementation profile that makes it the right choice for specific use cases and wrong for others.
SLH-DSA relies entirely on hash function computations (SHA-2 or SHA-3). It requires no NTT (Number Theoretic Transform) operations, unlike ML-KEM and ML-DSA. Any platform with hash function support can run SLH-DSA. The signatures are large: SLH-DSA-SHA2-128s (the small variant) produces 7,856-byte signatures; SLH-DSA-SHA2-128f (the fast variant) produces 17,088-byte signatures, compared to 3,309 bytes for ML-DSA-65. This size is acceptable for CA certificate issuance, firmware signing, and archival integrity checking, where signing is infrequent and the signature is stored alongside a large artefact.
SLH-DSA signing is significantly slower than ML-DSA for most parameter sets. The SHA2-128f (fast) variant signs in the order of milliseconds on x86-64. The SHA2-128s (small) variant signs in the order of tens to hundreds of milliseconds. SLH-DSA verification is fast (approximately 0.5 to 2 ms). For CA certificate issuance and firmware signing, where signing is infrequent and security conservatism is the priority, SLH-DSA's asymmetric performance profile is acceptable and its hash-function-only security basis provides diversification from ML-DSA's lattice assumptions. For high-rate signing workloads, ML-DSA is more appropriate.
SLH-DSA library coverage as of knowledge cutoff: liboqs (full parameter set coverage), the RustCrypto slh-dsa crate (pure-Rust FIPS 205 implementation, same type-safe API pattern as ml-kem), OpenSSL 3.5 (SLH-DSA support included), and wolfSSL. The same FIPS 140-3 validation caveats apply across all of them: check CMVP scope explicitly.
Selection framework: five criteria in priority order
Apply these criteria in order. The first question that eliminates an option ends the evaluation for that option on that deployment.
| Priority | Criterion | How to verify |
|---|---|---|
| 1 | FIPS 140-3 validation required? | Check NIST CMVP database for module certificate with ML-KEM (FIPS 203) or SLH-DSA (FIPS 205) in scope. AWS-LC-FIPS and wolfSSL FIPS module are the current candidates; verify specific certificate scope. If no validated module exists for your platform, use liboqs or RustCrypto as interim and plan for adoption when CMVP certificates are issued. |
| 2 | Target platform? | Server-side C: OpenSSL 3.5 or AWS-LC. Embedded C (Cortex-M class, low memory): wolfSSL with embedded configuration. Rust (non-FIPS): RustCrypto ml-kem/slh-dsa crates. Rust (FIPS context): aws-lc-rs crate. Existing OpenSSL-based application: OpenSSL 3.5 (path of least disruption). |
| 3 | Is the implementation FIPS 203/205 final (not Round 3 draft)? | Check library CHANGELOG for explicit FIPS 203/205 compliance statement. Verify key sizes against FIPS 203 Table 1 (ML-KEM-768: pk=1,184B, ct=1,088B). Run ACVTS test vectors if in doubt. Round 3 Kyber and FIPS 203 ML-KEM are not interoperable. |
| 4 | Active maintenance with security patch SLA? | liboqs: university-maintained open source, no commercial SLA. OpenSSL 3.5: maintained with security patches. AWS-LC: Amazon security patch SLA. wolfSSL: commercially supported. RustCrypto: community-maintained, no commercial SLA. aws-lc-rs: follows AWS-LC maintenance. |
| 5 | Does the API support crypto agility? | Prefer libraries where algorithm and parameter set selection is a runtime configuration parameter, not a compile-time constant. liboqs achieves this via identifier string. OpenSSL achieves this via EVP abstraction. RustCrypto achieves this via generic types (with compile-time selection, which is acceptable for most server deployments). Hardcoded algorithm names in application code require rewrites for parameter set changes. |
A note on assumptions: FIPS 140-3 validation status for ML-KEM implementations is in active flux around this article's publication date. The CMVP database is the authoritative source. Any specific validation status stated here carries the caveat that CMVP certificates are issued on an ongoing basis and the database should be queried directly at the point of selection. The framework above is stable; the specific validation status of individual modules is not.
Sources verified 2026-05-18. NIST FIPS 203 (ML-KEM), August 2024; NIST FIPS 204 (ML-DSA), August 2024; NIST FIPS 205 (SLH-DSA), August 2024; NIST FIPS 206 (FN-DSA), October 2024; NIST CMVP, https://csrc.nist.gov/projects/cryptographic-module-validation-program; NIST ACVTS; NIST CSWP 04282021; Open Quantum Safe project (liboqs), https://openquantumsafe.org/; AWS-LC GitHub; aws-lc-rs crate; BoringSSL; wolfSSL; OpenSSL 3.5 release notes; RustCrypto ml-kem, slh-dsa, ml-dsa crates; Kannwischer et al., IACR ePrint 2019/844; NIST IR 8413, 2022.