Implement the X25519MLKEM768 hybrid key exchange group per
draft-ietf-tls-ecdhe-mlkem-00, combining ML-KEM-768 (FIPS 203) with
X25519 for post-quantum/classical hybrid key agreement.
- New mlkem feature gating X25519MLKEM768 via boring's mlkem module
- fips feature now implies mlkem so PQ is always available in FIPS mode
- X25519MLKEM768 is the preferred (first) group in both FIPS and
non-FIPS configurations when mlkem is enabled
- Uses boring::mlkem for ML-KEM-768 and direct X25519 FFI for the
classical component (no SPKI overhead)
- Overrides start_and_complete() for server-side KEM encapsulation
- Wire format: ML-KEM component first in all encodings (client share
1216 bytes, server share 1120 bytes, shared secret 64 bytes)
- TLS 1.3 only (usable_for_version rejects TLS 1.2)
- Unit tests: hybrid round-trip, invalid share rejection, version
and FIPS flag checks
- E2E tests: self-to-self PQ TLS handshake, FIPS group assertions
- Cloudflare interop tests (ignored): verify kex=X25519MLKEM768 via
/cdn-cgi/trace for TLS 1.3, verify classical fallback for TLS 1.2
- Update README with PQ section, feature docs, and FIPS KX updates
- Bump boring/boring-sys from v4 to v5 (zero API breaks)
- Merge fips/fips-only into a single fips feature that both enables
FIPS-validated BoringSSL and restricts algorithms to SP 800-52r2
- Tighten FIPS KX groups to P-256 and P-384 only (aligned with
boring's fips202205 compliance policy)
- Remove ECDSA_P521_SHA512 from FIPS signature verification set
- Simplify fips feature to forward boring/fips only (drop redundant
boring-sys/fips)
- Add fips-precompiled as deprecated alias matching boring's naming
- Change default features to empty (TLS 1.2 now requires explicit
tls12 feature opt-in)
- Gate TLS 1.2 code paths properly so the crate compiles and passes
tests with default (TLS 1.3 only) features
- Update README to reflect current state: boring v5, feature docs,
FIPS mode documentation, workspace structure
This is just a dump of me figuring out how to interface with boring and rustls.
It works to establish a connection and exchange data but I haven't written real tests yet, nor did I cleanup the code or made the effort to make it look nice.
There is probably some code in here that should rather live in the `boring` crate.