ferritls
ferritls is a pure-Rust rustls
CryptoProvider: no C, no default assembly, no unsafe in the cryptographic
core, organized as a FIPS 140-3 cryptographic module boundary. It is a
maintained, fully auditable alternative to aws-lc-rs (C/assembly,
cmake, slow builds) and the unmaintained rustls-rustcrypto.
Highlights
- TLS 1.3 cipher suites: AES-128/256-GCM, AES-128-CCM (and CCM_8), ChaCha20-Poly1305
- Key exchange: X25519, secp256r1, secp384r1, post-quantum ML-KEM 512/768/1024 (FIPS 203) and the X25519MLKEM768 hybrid
- Certificate signatures: ECDSA P-256/384, RSA-PSS / PKCS#1 v1.5, Ed25519
- QUIC packet protection (RFC 9001) for the GCM and ChaCha suites
- Approved mode (
fipsfeature): NIST-approved algorithms only, SP 800-90A CTR-DRBG, power-on self-tests - Optional x86_64 hardware backend (AES-NI / SHA-NI):
ferritls-backend-x86_64, a separate crate registered at runtime (outside the FIPS boundary) - Tested against NIST/RFC/CAVP vectors, 2,300+ Wycheproof cases, cross-interop with rustls-ring, and continuous fuzzing
Usage
[]
= "0.9"
// Once per process, before building any TLS config:
default_provider.install_default?;
// rustls now uses ferritls by default:
let config = builder
.with_root_certificates
.with_no_client_auth;
Prefer to avoid process-global state? Pass the provider explicitly:
use Arc;
let provider = new;
let config = builder_with_provider
.with_safe_default_protocol_versions?
.with_root_certificates
.with_no_client_auth;
Detailed usage — server configuration, approved mode, QUIC, reqwest integration — lives in the API documentation.
Hardware backend (x86_64, optional)
[]
= "0.9"
// Once per process, before constructing any key object (x86_64 only;
// elsewhere this crate is empty and the block compiles away):
install?;
Details — probe/KAT failure modes, the fips-build refusal, and
performance numbers — are in the
ferritls-backend-x86_64 README.
Build requirements
The default simd feature uses the standard library's core::simd
(portable_simd), which on the stable toolchain requires
RUSTC_BOOTSTRAP=1 (this repository's .cargo/config.toml already
sets it):
# (a) keep simd
# or, in your Cargo.toml: # (b) scalar fallback
# ferritls-core = { version = "0.9", default-features = false }
Nightly toolchains need no variable; the requirement goes away once portable_simd stabilizes.
Testing
FERRITLS_TEST_NI=1
RUSTC_BOOTSTRAP=1 is already set by .cargo/config.toml, so the
commands above run as-is on stable. The full test matrix and
conventions live in AGENTS.md.
Benchmarks
Criterion benchmarks cover the cryptographic primitives and in-process TLS 1.3 handshakes (with a rustls-ring baseline):
To see where the three deployment configurations — scalar software,
core::simd software, and simd plus the installed x86_64 hardware
backend — stand against OpenSSL, run the comparison matrix (Linux,
OpenSSL development headers required). It measures both build
configurations, cross-checks ferritls and OpenSSL outputs byte-for-byte,
and prints a Markdown report:
Regression baselines, methodology (anchor ratios, fairness shapes) and platform notes are in docs/BENCHMARKS.md. CI only compile-checks the benches; measurements run locally.
FIPS 140-3 status
ferritls is organized as a FIPS 140-3 cryptographic module boundary
(the ferritls-core crate); it is not yet CMVP-validated. Every
fips() hook returns false, and the fips feature means "runs in
the approved-algorithm mode", not a certification claim. Roadmap:
docs/FIPS.md.
License
Apache-2.0 OR MIT (see LICENSE-APACHE and LICENSE-MIT). Contributors — human or AI agents — should read AGENTS.md first.