Skip to main content

crypto_rustls/
crypto_rustls.rs

1//! A [`rustls`](https://github.com/rustls/rustls) [`CryptoProvider`] backed by
2//! the stdx [`crypto`] crate.
3//!
4//! This crate lets rustls use the pure-Rust, `no_std`-friendly primitives from
5//! [`crypto`] instead of rustls' built-in `aws-lc-rs` or `ring` backends.
6//! Rustls is configured with `default-features = false`, so no C or
7//! assembly-backed cryptography is compiled in.
8//!
9//! # Supported algorithms
10//!
11//! * TLS 1.3 cipher suites: `TLS_AES_128_GCM_SHA256`,
12//!   `TLS_AES_256_GCM_SHA384`, `TLS_CHACHA20_POLY1305_SHA256`.
13//! * Key exchange: `X25519MLKEM768` (post-quantum hybrid, preferred),
14//!   `X25519`, `secp256r1` and `secp384r1`.
15//! * Signature verification: ECDSA P-256/P-384, Ed25519, RSA PKCS#1 v1.5 and
16//!   PSS, and ML-DSA-44/65/87 (FIPS 204).
17//! * Signing (for serving TLS or client certificates): ECDSA P-256/P-384,
18//!   Ed25519 and ML-DSA-44/65/87. RSA private keys are not supported.
19//! * QUIC (RFC 9001) packet protection for all three cipher suites.
20//!
21//! ML-DSA is supported in the "pure" mode required by RFC 9881 and the TLS 1.3
22//! ML-DSA profile (empty FIPS 204 context). Private keys must be in the RFC
23//! 9881 seed form; keys stored only as an expanded key are rejected because the
24//! seed cannot be recovered from them. OpenSSL's default `both` encoding (seed
25//! plus expanded key) is accepted.
26//!
27//! The `X25519MLKEM768` hybrid is offered first, so a post-quantum key share is
28//! sent by default in the ClientHello, while classical groups remain available
29//! for peers that do not support it. Encapsulation keys received from a peer
30//! are validated per FIPS 203 section 7.2 (modulus check); a malformed key
31//! share is rejected as `PeerMisbehaved::InvalidKeyShare`.
32//!
33//! RSA PKCS#1 v1.5 certificates are accepted both with the customary `NULL`
34//! `AlgorithmIdentifier` parameters and with the parameters absent (RFC 4055
35//! section 2.1).
36//!
37//! # Limitations
38//!
39//! * TLS 1.2 is not supported. Only TLS 1.3 cipher suites are provided.
40//! * RSA signing is not supported. The [`crypto`] crate implements RSA
41//!   verification only, so a TLS server (or a client using client
42//!   authentication) must use an ECDSA P-256/P-384, Ed25519 or ML-DSA private
43//!   key. RSA-signed certificate chains are still verified normally.
44//! * The curve implementations bind each curve to a single hash (P-256 with
45//!   SHA-256, P-384 with SHA-384), so the uncommon cross combinations are not
46//!   registered.
47//!
48//! # Usage
49//!
50//! Install this provider as the process default before building any rustls
51//! configuration:
52//!
53//! ```ignore
54//! crypto_rustls::install_default_rustls_provider();
55//! ```
56//!
57//! Or pass [`default_provider`] explicitly to
58//! `ClientConfig::builder_with_provider()` /
59//! `ServerConfig::builder_with_provider()`.
60
61mod aead;
62mod ciphersuites;
63mod hash;
64mod hmac;
65mod hybrid_key_exchange;
66mod key_exchange;
67mod quic;
68mod random;
69mod sign;
70mod verify;
71
72use rustls::crypto::CryptoProvider;
73
74/// Returns this crate's [`CryptoProvider`].
75///
76/// Install it with [`CryptoProvider::install_default`], or pass it to
77/// `ClientConfig::builder_with_provider()` /
78/// `ServerConfig::builder_with_provider()`.
79///
80/// The provider offers only TLS 1.3, prefers the `X25519MLKEM768`
81/// post-quantum hybrid key exchange, and supports QUIC.
82pub fn default_provider() -> CryptoProvider {
83    CryptoProvider {
84        cipher_suites: ciphersuites::ALL_CIPHER_SUITES.to_vec(),
85        kx_groups: key_exchange::KX_GROUPS.to_vec(),
86        signature_verification_algorithms: verify::ALGORITHMS,
87        secure_random: &random::RngProvider,
88        key_provider: &sign::Provider,
89    }
90}
91
92/// Installs [`default_provider`] as the process-default rustls
93/// [`CryptoProvider`].
94///
95/// This is the intended entry point when `rustls` (or `reqwest`) is compiled
96/// without a built-in cryptography provider, such as when using reqwest's
97/// `rustls-no-provider` feature. Call it once before building any rustls
98/// configuration.
99///
100/// The call is safe to repeat and never panics: the provider is installed only
101/// on the first call, and if a provider is already installed as the process
102/// default, that provider is left untouched.
103pub fn install_default_rustls_provider() {
104    static ONCE: std::sync::Once = std::sync::Once::new();
105    ONCE.call_once(|| {
106        let _ = default_provider().install_default();
107    });
108}