ferritls-rustls 0.9.1

rustls CryptoProvider adapter backed by ferritls-core (pure Rust)
Documentation

ferritls

English | 简体中文

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 (fips feature): 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

[dependencies]
ferritls-rustls = "0.9"
// Once per process, before building any TLS config:
ferritls_rustls::default_provider().install_default()?;

// rustls now uses ferritls by default:
let config = rustls::ClientConfig::builder()
    .with_root_certificates(roots)
    .with_no_client_auth();

Prefer to avoid process-global state? Pass the provider explicitly:

use std::sync::Arc;

let provider = Arc::new(ferritls_rustls::default_provider());
let config = rustls::ClientConfig::builder_with_provider(provider)
    .with_safe_default_protocol_versions()?
    .with_root_certificates(roots)
    .with_no_client_auth();

Detailed usage — server configuration, approved mode, QUIC, reqwest integration — lives in the API documentation.

Hardware backend (x86_64, optional)

[dependencies]
ferritls-backend-x86_64 = "0.9"
// Once per process, before constructing any key object (x86_64 only;
// elsewhere this crate is empty and the block compiles away):
#[cfg(target_arch = "x86_64")]
ferritls_backend_x86_64::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):

export RUSTC_BOOTSTRAP=1    # (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

cargo test --workspace                 # full suite (add --all-features for the ring cross-interop)
cargo test -p ferritls-core --no-default-features   # scalar fallback path
cargo test -p ferritls-core --features fips         # approved-mode gates
FERRITLS_TEST_NI=1 cargo test -p ferritls-rustls -p ferritls-interop  # x86_64: re-run on the AES-NI/SHA-NI backend
cargo clippy --workspace --all-targets -- -D warnings

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):

cargo bench -p ferritls-core                         # primitives (aead/hash/ecdh/sign/drbg/kem)
cargo bench -p ferritls-interop --bench handshake    # full TLS 1.3 handshake vs ring
cargo bench -p ferritls-backend-x86_64               # software vs Ni per record (x86_64)

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:

python3 tools/bench_matrix.py          # full matrix + report (~25 min)
python3 tools/bench_matrix.py --quick  # shortened smoke run

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.