rustls_mbedcrypto_provider/
lib.rs

1/* Copyright (c) Fortanix, Inc.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 */
7
8//! rustls-mbedcrypto-provider
9//!
10//! rustls-mbedcrypto-provider is a crypto provider for rustls based on [mbedtls].
11//!
12//! [mbedtls]: https://github.com/fortanix/rust-mbedtls
13
14// Require docs for public APIs, deny unsafe code, etc.
15#![forbid(unsafe_code, unused_must_use)]
16#![cfg_attr(not(bench), forbid(unstable_features))]
17#![deny(
18    clippy::alloc_instead_of_core,
19    clippy::clone_on_ref_ptr,
20    clippy::std_instead_of_core,
21    clippy::use_self,
22    clippy::upper_case_acronyms,
23    trivial_casts,
24    trivial_numeric_casts,
25    missing_docs,
26    unreachable_pub,
27    unused_import_braces,
28    unused_extern_crates,
29    unused_qualifications
30)]
31// Relax these clippy lints:
32// - ptr_arg: this triggers on references to type aliases that are Vec
33//   underneath.
34// - too_many_arguments: some things just need a lot of state, wrapping it
35//   doesn't necessarily make it easier to follow what's going on
36// - new_ret_no_self: we sometimes return `Arc<Self>`, which seems fine
37// - single_component_path_imports: our top-level `use log` import causes
38//   a false positive, https://github.com/rust-lang/rust-clippy/issues/5210
39// - new_without_default: for internal constructors, the indirection is not
40//   helpful
41#![allow(
42    clippy::too_many_arguments,
43    clippy::new_ret_no_self,
44    clippy::ptr_arg,
45    clippy::single_component_path_imports,
46    clippy::new_without_default,
47    unused_imports
48)]
49// Enable documentation for all features on docs.rs
50#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
51#![cfg_attr(bench, feature(test))]
52// TODO: enable this once we support use mbedtls without `std`
53// #![cfg_attr(not(test), no_std)]
54
55extern crate alloc;
56
57// This `extern crate` plus the `#![no_std]` attribute changes the default prelude from
58// `std::prelude` to `core::prelude`. That forces one to _explicitly_ import (`use`) everything that
59// is in `std::prelude` but not in `core::prelude`. This helps maintain no-std support as even
60// developers that are not interested in, or aware of, no-std support and / or that never run
61// `cargo build --no-default-features` locally will get errors when they rely on `std::prelude` API.
62// TODO: enable this once we support use mbedtls without `std`
63// #[cfg(not(test))]
64// extern crate std;
65
66// Import `test` sysroot crate for `Bencher` definitions.
67#[cfg(bench)]
68#[allow(unused_extern_crates)]
69extern crate test;
70
71// log for logging (optional).
72#[cfg(feature = "logging")]
73use log;
74
75#[cfg(not(feature = "logging"))]
76#[allow(unused_imports)]
77pub(crate) mod log {
78    macro_rules! ignore_log ( ($($tt:tt)*) => {{}} );
79    pub(crate) use ignore_log as trace;
80    pub(crate) use ignore_log as debug;
81    pub(crate) use ignore_log as warn;
82    pub(crate) use ignore_log as error;
83}
84
85/// Aead algorithms
86pub mod aead;
87pub(crate) mod agreement;
88pub(crate) mod error;
89#[cfg(feature = "fips")]
90pub(crate) mod fips_utils;
91/// Hash algorithms
92pub mod hash;
93/// Hmac algorithms
94pub mod hmac;
95/// Key exchange algorithms
96pub mod kx;
97
98#[cfg(feature = "self_tests")]
99pub mod self_tests;
100/// Message signing interfaces.
101pub mod sign;
102/// Supported signature verify algorithms
103pub mod signature_verify_algo;
104/// TLS1.2 ciphersuites implementation.
105#[cfg(feature = "tls12")]
106pub(crate) mod tls12;
107/// TLS1.3 ciphersuites implementation.
108pub(crate) mod tls13;
109
110use mbedtls::rng::Random;
111use rustls::{
112    crypto::{CryptoProvider, KeyProvider, SecureRandom, WebPkiSupportedAlgorithms},
113    SignatureScheme, SupportedCipherSuite,
114};
115
116/// RNG supported by *mbedtls*
117pub mod rng {
118
119    /// Type alias for the a RNG(implemented by using [`mbedtls::rng::CtrDrbg`]) supported
120    /// by [*mbedtls*], it always use [`mbedtls::rng::OsEntropy`].
121    ///
122    /// [*mbedtls*]: https://github.com/fortanix/rust-mbedtls
123    #[cfg(not(any(target_env = "sgx", feature = "rdrand")))]
124    pub type MbedRng = mbedtls::rng::CtrDrbg;
125
126    /// Get a RNG supported by [*mbedtls*].
127    ///
128    /// The RNG is implemented by using [`mbedtls::rng::CtrDrbg`] and it always uses
129    /// [`mbedtls::rng::OsEntropy`].
130    ///
131    /// [*mbedtls*]: https://github.com/fortanix/rust-mbedtls
132    #[cfg(not(any(target_env = "sgx", feature = "rdrand")))]
133    pub fn rng_new() -> Option<MbedRng> {
134        let entropy = alloc::sync::Arc::new(mbedtls::rng::OsEntropy::new());
135        mbedtls::rng::CtrDrbg::new(entropy, None).ok()
136    }
137
138    /// Type alias for the a RNG(implemented by using [`mbedtls::rng::Rdrand`]) supported by
139    /// [*mbedtls*].
140    ///
141    /// [*mbedtls*]: https://github.com/fortanix/rust-mbedtls
142    #[cfg(any(target_env = "sgx", feature = "rdrand"))]
143    pub type MbedRng = mbedtls::rng::Rdrand;
144
145    /// Get a RNG supported by [*mbedtls*].
146    ///
147    /// The RNG is implemented by using [`mbedtls::rng::Rdrand`].
148    ///
149    /// [*mbedtls*]: https://github.com/fortanix/rust-mbedtls
150    #[cfg(any(target_env = "sgx", feature = "rdrand"))]
151    pub fn rng_new() -> Option<MbedRng> {
152        Some(mbedtls::rng::Rdrand)
153    }
154}
155
156/// returns a `CryptoProvider` backed by the [*mbedtls*] crate.
157///
158/// [*mbedtls*]: https://github.com/fortanix/rust-mbedtls
159pub fn mbedtls_crypto_provider() -> CryptoProvider {
160    CryptoProvider {
161        cipher_suites: ALL_CIPHER_SUITES.to_vec(),
162        kx_groups: ALL_KX_GROUPS.to_vec(),
163        signature_verification_algorithms: SUPPORTED_SIG_ALGS,
164        secure_random: &MbedtlsSecureRandom,
165        key_provider: &MbedtlsKeyProvider,
166    }
167}
168
169#[derive(Debug)]
170/// Implements `SecureRandom` using `mbedtls`
171pub struct MbedtlsSecureRandom;
172
173impl SecureRandom for MbedtlsSecureRandom {
174    fn fill(&self, buf: &mut [u8]) -> Result<(), rustls::crypto::GetRandomFailed> {
175        rng::rng_new()
176            .ok_or(rustls::crypto::GetRandomFailed)?
177            .random(buf)
178            .map_err(|_| rustls::crypto::GetRandomFailed)
179    }
180}
181
182#[derive(Debug)]
183/// Implements `KeyProvider` using `mbedtls`
184pub struct MbedtlsKeyProvider;
185
186impl KeyProvider for MbedtlsKeyProvider {
187    fn load_private_key(
188        &self,
189        key_der: webpki::types::PrivateKeyDer<'static>,
190    ) -> Result<alloc::sync::Arc<dyn rustls::sign::SigningKey>, rustls::Error> {
191        Ok(alloc::sync::Arc::new(sign::MbedTlsPkSigningKeyWrapper::new(
192            &key_der,
193            rng::rng_new,
194        )?))
195    }
196}
197
198/// The cipher suite configuration that an application should use by default.
199///
200/// This will be [`ALL_CIPHER_SUITES`] sans any supported cipher suites that
201/// shouldn't be enabled by most applications.
202pub static DEFAULT_CIPHER_SUITES: &[SupportedCipherSuite] = ALL_CIPHER_SUITES;
203
204/// A list of all the cipher suites supported by the rustls *mbedtls* provider.
205pub static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = &[
206    // TLS1.3 suites
207    tls13::TLS13_AES_256_GCM_SHA384,
208    tls13::TLS13_AES_128_GCM_SHA256,
209    tls13::TLS13_CHACHA20_POLY1305_SHA256,
210    // TLS1.2 suites
211    #[cfg(feature = "tls12")]
212    tls12::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
213    #[cfg(feature = "tls12")]
214    tls12::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
215    #[cfg(feature = "tls12")]
216    tls12::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
217    #[cfg(feature = "tls12")]
218    tls12::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
219    #[cfg(feature = "tls12")]
220    tls12::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
221    #[cfg(feature = "tls12")]
222    tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
223    #[cfg(feature = "tls12")]
224    tls12::TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
225    #[cfg(feature = "tls12")]
226    tls12::TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
227    #[cfg(feature = "tls12")]
228    tls12::TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
229];
230
231/// All defined cipher suites supported by *mbedtls* appear in this module.
232pub mod cipher_suite {
233    #[cfg(feature = "tls12")]
234    pub use super::tls12::{
235        TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
236        TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
237        TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
238        TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
239    };
240    pub use super::tls13::{TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384, TLS13_CHACHA20_POLY1305_SHA256};
241}
242
243/// A `WebPkiSupportedAlgorithms` value that reflects pki's capabilities when
244/// compiled against *mbedtls*.
245pub static SUPPORTED_SIG_ALGS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms {
246    all: &[
247        signature_verify_algo::ECDSA_P256_SHA256,
248        signature_verify_algo::ECDSA_P256_SHA384,
249        signature_verify_algo::ECDSA_P384_SHA256,
250        signature_verify_algo::ECDSA_P384_SHA384,
251        signature_verify_algo::RSA_PSS_SHA256,
252        signature_verify_algo::RSA_PSS_SHA384,
253        signature_verify_algo::RSA_PSS_SHA512,
254        signature_verify_algo::RSA_PKCS1_SHA256,
255        signature_verify_algo::RSA_PKCS1_SHA384,
256        signature_verify_algo::RSA_PKCS1_SHA512,
257    ],
258    mapping: &[
259        (
260            SignatureScheme::ECDSA_NISTP384_SHA384,
261            &[
262                signature_verify_algo::ECDSA_P384_SHA384,
263                signature_verify_algo::ECDSA_P256_SHA384,
264            ],
265        ),
266        (
267            SignatureScheme::ECDSA_NISTP256_SHA256,
268            &[
269                signature_verify_algo::ECDSA_P256_SHA256,
270                signature_verify_algo::ECDSA_P384_SHA256,
271            ],
272        ),
273        (SignatureScheme::RSA_PSS_SHA512, &[signature_verify_algo::RSA_PSS_SHA512]),
274        (SignatureScheme::RSA_PSS_SHA384, &[signature_verify_algo::RSA_PSS_SHA384]),
275        (SignatureScheme::RSA_PSS_SHA256, &[signature_verify_algo::RSA_PSS_SHA256]),
276        (SignatureScheme::RSA_PKCS1_SHA512, &[signature_verify_algo::RSA_PKCS1_SHA512]),
277        (SignatureScheme::RSA_PKCS1_SHA384, &[signature_verify_algo::RSA_PKCS1_SHA384]),
278        (SignatureScheme::RSA_PKCS1_SHA256, &[signature_verify_algo::RSA_PKCS1_SHA256]),
279    ],
280};
281
282/// All defined key exchange groups supported by *mbedtls* appear in this module.
283///
284/// [`ALL_KX_GROUPS`] is provided as an array of all of these values.
285pub mod kx_group {
286    pub use super::kx::FFDHE2048;
287    pub use super::kx::FFDHE3072;
288    pub use super::kx::FFDHE4096;
289    pub use super::kx::FFDHE6144;
290    pub use super::kx::FFDHE8192;
291
292    pub use super::kx::SECP256R1;
293    pub use super::kx::SECP384R1;
294    pub use super::kx::SECP521R1;
295    pub use super::kx::X25519;
296}
297
298pub use kx::ALL_KX_GROUPS;