clia_rustls_mod/crypto/
mod.rs

1use alloc::boxed::Box;
2use alloc::sync::Arc;
3use alloc::vec::Vec;
4use core::fmt::Debug;
5
6#[cfg(not(feature = "std"))]
7use once_cell::race::OnceBox;
8#[cfg(feature = "std")]
9use once_cell::sync::OnceCell;
10use pki_types::PrivateKeyDer;
11use zeroize::Zeroize;
12
13use crate::sign::SigningKey;
14pub use crate::webpki::{
15    verify_tls12_signature, verify_tls13_signature, WebPkiSupportedAlgorithms,
16};
17#[cfg(all(doc, feature = "tls12"))]
18use crate::Tls12CipherSuite;
19#[cfg(doc)]
20use crate::{
21    client, crypto, server, sign, ClientConfig, ConfigBuilder, ServerConfig, SupportedCipherSuite,
22    Tls13CipherSuite,
23};
24use crate::{suites, Error, NamedGroup, ProtocolVersion, SupportedProtocolVersion};
25
26/// *ring* based CryptoProvider.
27#[cfg(feature = "ring")]
28pub mod ring;
29
30/// aws-lc-rs-based CryptoProvider.
31#[cfg(feature = "aws_lc_rs")]
32pub mod aws_lc_rs;
33
34/// TLS message encryption/decryption interfaces.
35pub mod cipher;
36
37/// Hashing interfaces.
38pub mod hash;
39
40/// HMAC interfaces.
41pub mod hmac;
42
43#[cfg(feature = "tls12")]
44/// Cryptography specific to TLS1.2.
45pub mod tls12;
46
47/// Cryptography specific to TLS1.3.
48pub mod tls13;
49
50/// Hybrid public key encryption (RFC 9180).
51#[doc(hidden)]
52pub mod hpke;
53
54// Message signing interfaces. Re-exported under rustls::sign. Kept crate-internal here to
55// avoid having two import paths to the same types.
56pub(crate) mod signer;
57
58pub use crate::msgs::handshake::KeyExchangeAlgorithm;
59pub use crate::rand::GetRandomFailed;
60pub use crate::suites::CipherSuiteCommon;
61
62/// Controls core cryptography used by rustls.
63///
64/// This crate comes with two built-in options, provided as
65/// `CryptoProvider` structures:
66///
67/// - [`crypto::aws_lc_rs::default_provider`]: (behind the `aws_lc_rs` feature,
68///   which is enabled by default).  This provider uses the [aws-lc-rs](https://github.com/aws/aws-lc-rs)
69///   crate.  The `fips` crate feature makes this option use FIPS140-3-approved cryptography.
70/// - [`crypto::ring::default_provider`]: (behind the `ring` crate feature, which
71///   is optional).  This provider uses the [*ring*](https://github.com/briansmith/ring)
72///   crate.
73///
74/// This structure provides defaults. Everything in it can be overridden at
75/// runtime by replacing field values as needed.
76///
77/// # Using the per-process default `CryptoProvider`
78///
79/// There is the concept of an implicit default provider, configured at run-time once in
80/// a given process.
81///
82/// It is used for functions like [`ClientConfig::builder()`] and [`ServerConfig::builder()`].
83///
84/// The intention is that an application can specify the [`CryptoProvider`] they wish to use
85/// once, and have that apply to the variety of places where their application does TLS
86/// (which may be wrapped inside other libraries).
87/// They should do this by calling [`CryptoProvider::install_default()`] early on.
88///
89/// To achieve this goal:
90///
91/// - _libraries_ should use [`ClientConfig::builder()`]/[`ServerConfig::builder()`]
92///   or otherwise rely on the [`CryptoProvider::get_default()`] provider.
93/// - _applications_ should call [`CryptoProvider::install_default()`] early
94///   in their `fn main()`.
95///
96/// # Using a specific `CryptoProvider`
97///
98/// Supply the provider when constructing your [`ClientConfig`] or [`ServerConfig`]:
99///
100/// - [`ClientConfig::builder_with_provider()`]
101/// - [`ServerConfig::builder_with_provider()`]
102///
103/// When creating and configuring a webpki-backed client or server certificate verifier, a choice of
104/// provider is also needed to start the configuration process:
105///
106/// - [`client::WebPkiServerVerifier::builder_with_provider()`]
107/// - [`server::WebPkiClientVerifier::builder_with_provider()`]
108///
109/// # Making a custom `CryptoProvider`
110///
111/// Your goal will be to populate a [`crypto::CryptoProvider`] struct instance.
112///
113/// ## Which elements are required?
114///
115/// There is no requirement that the individual elements (`SupportedCipherSuite`, `SupportedKxGroup`,
116/// `SigningKey`, etc.) come from the same crate.  It is allowed and expected that uninteresting
117/// elements would be delegated back to one of the default providers (statically) or a parent
118/// provider (dynamically).
119///
120/// For example, if we want to make a provider that just overrides key loading in the config builder
121/// API ([`ConfigBuilder::with_single_cert`] etc.), it might look like this:
122///
123/// ```
124/// # #[cfg(feature = "aws_lc_rs")] {
125/// # use std::sync::Arc;
126/// # mod fictious_hsm_api { pub fn load_private_key(key_der: pki_types::PrivateKeyDer<'static>) -> ! { unreachable!(); } }
127/// use rustls::crypto::aws_lc_rs;
128///
129/// pub fn provider() -> rustls::crypto::CryptoProvider {
130///   rustls::crypto::CryptoProvider{
131///     key_provider: &HsmKeyLoader,
132///     ..aws_lc_rs::default_provider()
133///   }
134/// }
135///
136/// #[derive(Debug)]
137/// struct HsmKeyLoader;
138///
139/// impl rustls::crypto::KeyProvider for HsmKeyLoader {
140///     fn load_private_key(&self, key_der: pki_types::PrivateKeyDer<'static>) -> Result<Arc<dyn rustls::sign::SigningKey>, rustls::Error> {
141///          fictious_hsm_api::load_private_key(key_der)
142///     }
143/// }
144/// # }
145/// ```
146///
147/// ## References to the individual elements
148///
149/// The elements are documented separately:
150///
151/// - **Random** - see [`crypto::SecureRandom::fill()`].
152/// - **Cipher suites** - see [`SupportedCipherSuite`], [`Tls12CipherSuite`], and
153///   [`Tls13CipherSuite`].
154/// - **Key exchange groups** - see [`crypto::SupportedKxGroup`].
155/// - **Signature verification algorithms** - see [`crypto::WebPkiSupportedAlgorithms`].
156/// - **Authentication key loading** - see [`crypto::KeyProvider::load_private_key()`] and
157///   [`sign::SigningKey`].
158///
159/// # Example code
160///
161/// See [provider-example/] for a full client and server example that uses
162/// cryptography from the [rust-crypto] and [dalek-cryptography] projects.
163///
164/// ```shell
165/// $ cargo run --example client | head -3
166/// Current ciphersuite: TLS13_CHACHA20_POLY1305_SHA256
167/// HTTP/1.1 200 OK
168/// Content-Type: text/html; charset=utf-8
169/// Content-Length: 19899
170/// ```
171///
172/// [provider-example/]: https://github.com/rustls/rustls/tree/main/provider-example/
173/// [rust-crypto]: https://github.com/rustcrypto
174/// [dalek-cryptography]: https://github.com/dalek-cryptography
175///
176/// # FIPS-approved cryptography
177/// The `fips` crate feature enables use of the `aws-lc-rs` crate in FIPS mode.
178///
179/// You can verify the configuration at runtime by checking
180/// [`ServerConfig::fips()`]/[`ClientConfig::fips()`] return `true`.
181#[derive(Debug, Clone)]
182pub struct CryptoProvider {
183    /// List of supported ciphersuites, in preference order -- the first element
184    /// is the highest priority.
185    ///
186    /// The `SupportedCipherSuite` type carries both configuration and implementation.
187    ///
188    /// A valid `CryptoProvider` must ensure that all cipher suites are accompanied by at least
189    /// one matching key exchange group in [`CryptoProvider::kx_groups`].
190    pub cipher_suites: Vec<suites::SupportedCipherSuite>,
191
192    /// List of supported key exchange groups, in preference order -- the
193    /// first element is the highest priority.
194    ///
195    /// The first element in this list is the _default key share algorithm_,
196    /// and in TLS1.3 a key share for it is sent in the client hello.
197    ///
198    /// The `SupportedKxGroup` type carries both configuration and implementation.
199    pub kx_groups: Vec<&'static dyn SupportedKxGroup>,
200
201    /// List of signature verification algorithms for use with webpki.
202    ///
203    /// These are used for both certificate chain verification and handshake signature verification.
204    ///
205    /// This is called by [`ConfigBuilder::with_root_certificates()`],
206    /// [`server::WebPkiClientVerifier::builder_with_provider()`] and
207    /// [`client::WebPkiServerVerifier::builder_with_provider()`].
208    pub signature_verification_algorithms: WebPkiSupportedAlgorithms,
209
210    /// Source of cryptographically secure random numbers.
211    pub secure_random: &'static dyn SecureRandom,
212
213    /// Provider for loading private [SigningKey]s from [PrivateKeyDer].
214    pub key_provider: &'static dyn KeyProvider,
215}
216
217impl CryptoProvider {
218    /// Sets this `CryptoProvider` as the default for this process.
219    ///
220    /// This can be called successfully at most once in any process execution.
221    ///
222    /// Call this early in your process to configure which provider is used for
223    /// the provider.  The configuration should happen before any use of
224    /// [`ClientConfig::builder()`] or [`ServerConfig::builder()`].
225    #[cfg(feature = "std")]
226    pub fn install_default(self) -> Result<(), Arc<Self>> {
227        PROCESS_DEFAULT_PROVIDER.set(Arc::new(self))
228    }
229
230    /// Sets this `CryptoProvider` as the default for this process.
231    ///
232    /// This can be called successfully at most once in any process execution.
233    ///
234    /// Call this early in your process to configure which provider is used for
235    /// the provider.  The configuration should happen before any use of
236    /// [`ClientConfig::builder()`] or [`ServerConfig::builder()`].
237    #[cfg(not(feature = "std"))]
238    pub fn install_default(self) -> Result<(), Box<Arc<Self>>> {
239        PROCESS_DEFAULT_PROVIDER.set(Box::new(Arc::new(self)))
240    }
241
242    /// Returns the default `CryptoProvider` for this process.
243    ///
244    /// This will be `None` if no default has been set yet.
245    pub fn get_default() -> Option<&'static Arc<Self>> {
246        PROCESS_DEFAULT_PROVIDER.get()
247    }
248
249    /// An internal function that:
250    ///
251    /// - gets the pre-installed default, or
252    /// - installs one `from_crate_features()`, or else
253    /// - panics about the need to call [`CryptoProvider::install_default()`]
254    pub(crate) fn get_default_or_install_from_crate_features() -> &'static Arc<Self> {
255        if let Some(provider) = Self::get_default() {
256            return provider;
257        }
258
259        let provider = Self::from_crate_features()
260            .expect("no process-level CryptoProvider available -- call CryptoProvider::install_default() before this point");
261        // Ignore the error resulting from us losing a race, and accept the outcome.
262        let _ = provider.install_default();
263        Self::get_default().unwrap()
264    }
265
266    /// Returns a provider named unambiguously by rustls crate features.
267    ///
268    /// This function returns `None` if the crate features are ambiguous (ie, specify two
269    /// providers), or specify no providers.  In both cases the application should
270    /// explicitly specify the provider to use with [`CryptoProvider::install_default`].
271    fn from_crate_features() -> Option<Self> {
272        #[cfg(all(feature = "ring", not(feature = "aws_lc_rs")))]
273        {
274            return Some(ring::default_provider());
275        }
276
277        #[cfg(all(feature = "aws_lc_rs", not(feature = "ring")))]
278        {
279            return Some(aws_lc_rs::default_provider());
280        }
281
282        #[allow(unreachable_code)]
283        None
284    }
285
286    /// Returns `true` if this `CryptoProvider` is operating in FIPS mode.
287    ///
288    /// This covers only the cryptographic parts of FIPS approval.  There are
289    /// also TLS protocol-level recommendations made by NIST.  You should
290    /// prefer to call [`ClientConfig::fips()`] or [`ServerConfig::fips()`]
291    /// which take these into account.
292    pub fn fips(&self) -> bool {
293        let Self {
294            cipher_suites,
295            kx_groups,
296            signature_verification_algorithms,
297            secure_random,
298            key_provider,
299        } = self;
300        cipher_suites.iter().all(|cs| cs.fips())
301            && kx_groups.iter().all(|kx| kx.fips())
302            && signature_verification_algorithms.fips()
303            && secure_random.fips()
304            && key_provider.fips()
305    }
306}
307
308#[cfg(feature = "std")]
309static PROCESS_DEFAULT_PROVIDER: OnceCell<Arc<CryptoProvider>> = OnceCell::new();
310#[cfg(not(feature = "std"))]
311static PROCESS_DEFAULT_PROVIDER: OnceBox<Arc<CryptoProvider>> = OnceBox::new();
312
313/// A source of cryptographically secure randomness.
314pub trait SecureRandom: Send + Sync + Debug {
315    /// Fill the given buffer with random bytes.
316    ///
317    /// The bytes must be sourced from a cryptographically secure random number
318    /// generator seeded with good quality, secret entropy.
319    ///
320    /// This is used for all randomness required by rustls, but not necessarily
321    /// randomness required by the underlying cryptography library.  For example:
322    /// [`SupportedKxGroup::start()`] requires random material to generate
323    /// an ephemeral key exchange key, but this is not included in the interface with
324    /// rustls: it is assumed that the cryptography library provides for this itself.
325    fn fill(&self, buf: &mut [u8]) -> Result<(), GetRandomFailed>;
326
327    /// Return `true` if this is backed by a FIPS-approved implementation.
328    fn fips(&self) -> bool {
329        false
330    }
331}
332
333/// A mechanism for loading private [SigningKey]s from [PrivateKeyDer].
334///
335/// This trait is intended to be used with private key material that is sourced from DER,
336/// such as a private-key that may be present on-disk. It is not intended to be used with
337/// keys held in hardware security modules (HSMs) or physical tokens. For these use-cases
338/// see the Rustls manual section on [customizing private key usage].
339///
340/// [customizing private key usage]: <https://docs.rs/rustls/latest/rustls/manual/_03_howto/index.html#customising-private-key-usage>
341pub trait KeyProvider: Send + Sync + Debug {
342    /// Decode and validate a private signing key from `key_der`.
343    ///
344    /// This is used by [`ConfigBuilder::with_client_auth_cert()`], [`ConfigBuilder::with_single_cert()`],
345    /// and [`ConfigBuilder::with_single_cert_with_ocsp()`].  The key types and formats supported by this
346    /// function directly defines the key types and formats supported in those APIs.
347    ///
348    /// Return an error if the key type encoding is not supported, or if the key fails validation.
349    fn load_private_key(
350        &self,
351        key_der: PrivateKeyDer<'static>,
352    ) -> Result<Arc<dyn SigningKey>, Error>;
353
354    /// Return `true` if this is backed by a FIPS-approved implementation.
355    ///
356    /// If this returns `true`, that must be the case for all possible key types
357    /// supported by [`KeyProvider::load_private_key()`].
358    fn fips(&self) -> bool {
359        false
360    }
361}
362
363/// A supported key exchange group.
364///
365/// This type carries both configuration and implementation. Specifically,
366/// it has a TLS-level name expressed using the [`NamedGroup`] enum, and
367/// a function which produces a [`ActiveKeyExchange`].
368///
369/// Compare with [`NamedGroup`], which carries solely a protocol identifier.
370pub trait SupportedKxGroup: Send + Sync + Debug {
371    /// Start a key exchange.
372    ///
373    /// This will prepare an ephemeral secret key in the supported group, and a corresponding
374    /// public key. The key exchange can be completed by calling [ActiveKeyExchange#complete]
375    /// or discarded.
376    ///
377    /// # Errors
378    ///
379    /// This can fail if the random source fails during ephemeral key generation.
380    fn start(&self) -> Result<Box<dyn ActiveKeyExchange>, Error>;
381
382    /// Start and complete a key exchange, in one operation.
383    ///
384    /// The default implementation for this calls `start()` and then calls
385    /// `complete()` on the result.  This is suitable for Diffie-Hellman-like
386    /// key exchange algorithms, where there is not a data dependency between
387    /// our key share (named "pub_key" in this API) and the peer's (`peer_pub_key`).
388    ///
389    /// If there is such a data dependency (like key encapsulation mechanisms), this
390    /// function should be implemented.
391    fn start_and_complete(&self, peer_pub_key: &[u8]) -> Result<CompletedKeyExchange, Error> {
392        let kx = self.start()?;
393
394        Ok(CompletedKeyExchange {
395            group: kx.group(),
396            pub_key: kx.pub_key().to_vec(),
397            secret: kx.complete(peer_pub_key)?,
398        })
399    }
400
401    /// Named group the SupportedKxGroup operates in.
402    ///
403    /// If the `NamedGroup` enum does not have a name for the algorithm you are implementing,
404    /// you can use [`NamedGroup::Unknown`].
405    fn name(&self) -> NamedGroup;
406
407    /// Return `true` if this is backed by a FIPS-approved implementation.
408    fn fips(&self) -> bool {
409        false
410    }
411}
412
413/// An in-progress key exchange originating from a [`SupportedKxGroup`].
414pub trait ActiveKeyExchange: Send + Sync {
415    /// Completes the key exchange, given the peer's public key.
416    ///
417    /// This method must return an error if `peer_pub_key` is invalid: either
418    /// mis-encoded, or an invalid public key (such as, but not limited to, being
419    /// in a small order subgroup).
420    ///
421    /// If the key exchange algorithm is FFDHE, the result must be left-padded with zeros,
422    /// as required by [RFC 8446](https://www.rfc-editor.org/rfc/rfc8446#section-7.4.1)
423    /// (see [`complete_for_tls_version()`](Self::complete_for_tls_version) for more details).
424    ///
425    /// The shared secret is returned as a [`SharedSecret`] which can be constructed
426    /// from a `&[u8]`.
427    ///
428    /// This consumes and so terminates the [`ActiveKeyExchange`].
429    fn complete(self: Box<Self>, peer_pub_key: &[u8]) -> Result<SharedSecret, Error>;
430
431    /// Completes the key exchange for the given TLS version, given the peer's public key.
432    ///
433    /// Note that finite-field Diffie–Hellman key exchange has different requirements for the derived
434    /// shared secret in TLS 1.2 and TLS 1.3 (ECDHE key exchange is the same in TLS 1.2 and TLS 1.3):
435    ///
436    /// In TLS 1.2, the calculated secret is required to be stripped of leading zeros
437    /// [(RFC 5246)](https://www.rfc-editor.org/rfc/rfc5246#section-8.1.2).
438    ///
439    /// In TLS 1.3, the calculated secret is required to be padded with leading zeros to be the same
440    /// byte-length as the group modulus [(RFC 8446)](https://www.rfc-editor.org/rfc/rfc8446#section-7.4.1).
441    ///
442    /// The default implementation of this method delegates to [`complete()`](Self::complete) assuming it is
443    /// implemented for TLS 1.3 (i.e., for FFDHE KX, removes padding as needed). Implementers of this trait
444    /// are encouraged to just implement [`complete()`](Self::complete) assuming TLS 1.3, and let the default
445    /// implementation of this method handle TLS 1.2-specific requirements.
446    ///
447    /// This method must return an error if `peer_pub_key` is invalid: either
448    /// mis-encoded, or an invalid public key (such as, but not limited to, being
449    /// in a small order subgroup).
450    ///
451    /// The shared secret is returned as a [`SharedSecret`] which can be constructed
452    /// from a `&[u8]`.
453    ///
454    /// This consumes and so terminates the [`ActiveKeyExchange`].
455    fn complete_for_tls_version(
456        self: Box<Self>,
457        peer_pub_key: &[u8],
458        tls_version: &SupportedProtocolVersion,
459    ) -> Result<SharedSecret, Error> {
460        if tls_version.version != ProtocolVersion::TLSv1_2 {
461            return self.complete(peer_pub_key);
462        }
463
464        let group = self.group();
465        let mut complete_res = self.complete(peer_pub_key)?;
466        if group.key_exchange_algorithm() == KeyExchangeAlgorithm::DHE {
467            complete_res.strip_leading_zeros();
468        }
469        Ok(complete_res)
470    }
471
472    /// Return the public key being used.
473    ///
474    /// For ECDHE, the encoding required is defined in
475    /// [RFC8446 section 4.2.8.2](https://www.rfc-editor.org/rfc/rfc8446#section-4.2.8.2).
476    ///
477    /// For FFDHE, the encoding required is defined in
478    /// [RFC8446 section 4.2.8.1](https://www.rfc-editor.org/rfc/rfc8446#section-4.2.8.1).
479    fn pub_key(&self) -> &[u8];
480
481    /// Return the group being used.
482    fn group(&self) -> NamedGroup;
483}
484
485/// The result from [`SupportedKxGroup::start_and_complete()`].
486pub struct CompletedKeyExchange {
487    /// Which group was used.
488    pub group: NamedGroup,
489
490    /// Our key share (sometimes a public key).
491    pub pub_key: Vec<u8>,
492
493    /// The computed shared secret.
494    pub secret: SharedSecret,
495}
496
497/// The result from [`ActiveKeyExchange::complete`].
498pub struct SharedSecret {
499    buf: Vec<u8>,
500    offset: usize,
501}
502
503impl SharedSecret {
504    /// Returns the shared secret as a slice of bytes.
505    pub fn secret_bytes(&self) -> &[u8] {
506        &self.buf[self.offset..]
507    }
508
509    /// Removes leading zeros from `secret_bytes()` by adjusting the `offset`.
510    ///
511    /// This function does not re-allocate.
512    fn strip_leading_zeros(&mut self) {
513        let start = self
514            .secret_bytes()
515            .iter()
516            .enumerate()
517            .find(|(_i, x)| **x != 0)
518            .map(|(i, _x)| i)
519            .unwrap_or(self.secret_bytes().len());
520        self.offset += start;
521    }
522}
523
524impl Drop for SharedSecret {
525    fn drop(&mut self) {
526        self.buf.zeroize();
527    }
528}
529
530impl From<&[u8]> for SharedSecret {
531    fn from(source: &[u8]) -> Self {
532        Self {
533            buf: source.to_vec(),
534            offset: 0,
535        }
536    }
537}
538
539/// This function returns a [`CryptoProvider`] that uses
540/// FIPS140-3-approved cryptography.
541///
542/// Using this function expresses in your code that you require
543/// FIPS-approved cryptography, and will not compile if you make
544/// a mistake with cargo features.
545///
546/// See our [FIPS documentation](crate::manual::_06_fips) for
547/// more detail.
548///
549/// Install this as the process-default provider, like:
550///
551/// ```rust
552/// # #[cfg(feature = "fips")] {
553/// rustls::crypto::default_fips_provider().install_default()
554///     .expect("default provider already set elsewhere");
555/// # }
556/// ```
557///
558/// You can also use this explicitly, like:
559///
560/// ```rust
561/// # #[cfg(feature = "fips")] {
562/// # let root_store = rustls::RootCertStore::empty();
563/// let config = rustls::ClientConfig::builder_with_provider(
564///         rustls::crypto::default_fips_provider().into()
565///     )
566///     .with_safe_default_protocol_versions()
567///     .unwrap()
568///     .with_root_certificates(root_store)
569///     .with_no_client_auth();
570/// # }
571/// ```
572#[cfg(any(feature = "fips", docsrs))]
573#[cfg_attr(docsrs, doc(cfg(feature = "fips")))]
574pub fn default_fips_provider() -> CryptoProvider {
575    aws_lc_rs::default_provider()
576}
577
578#[cfg(test)]
579mod tests {
580    use std::vec;
581
582    use super::SharedSecret;
583
584    #[test]
585    fn test_shared_secret_strip_leading_zeros() {
586        let test_cases = [
587            (vec![0, 1], vec![1]),
588            (vec![1], vec![1]),
589            (vec![1, 0, 2], vec![1, 0, 2]),
590            (vec![0, 0, 1, 2], vec![1, 2]),
591            (vec![0, 0, 0], vec![]),
592            (vec![], vec![]),
593        ];
594        for (buf, expected) in test_cases {
595            let mut secret = SharedSecret::from(&buf[..]);
596            assert_eq!(secret.secret_bytes(), buf);
597            secret.strip_leading_zeros();
598            assert_eq!(secret.secret_bytes(), expected);
599        }
600    }
601}