rustls/crypto/aws_lc_rs/
mod.rs

1use alloc::vec::Vec;
2
3// aws-lc-rs has a -- roughly -- ring-compatible API, so we just reuse all that
4// glue here.  The shared files should always use `super::ring_like` to access a
5// ring-compatible crate, and `super::ring_shim` to bridge the gaps where they are
6// small.
7pub(crate) use aws_lc_rs as ring_like;
8use pki_types::PrivateKeyDer;
9use webpki::aws_lc_rs as webpki_algs;
10
11use crate::crypto::{CryptoProvider, KeyProvider, SecureRandom, SupportedKxGroup};
12use crate::enums::SignatureScheme;
13use crate::rand::GetRandomFailed;
14use crate::sign::SigningKey;
15use crate::suites::SupportedCipherSuite;
16use crate::sync::Arc;
17use crate::webpki::WebPkiSupportedAlgorithms;
18use crate::{Error, OtherError};
19
20/// Hybrid public key encryption (HPKE).
21pub mod hpke;
22/// Post-quantum secure algorithms.
23pub(crate) mod pq;
24/// Using software keys for authentication.
25pub mod sign;
26
27#[path = "../ring/hash.rs"]
28pub(crate) mod hash;
29#[path = "../ring/hmac.rs"]
30pub(crate) mod hmac;
31#[path = "../ring/kx.rs"]
32pub(crate) mod kx;
33#[path = "../ring/quic.rs"]
34pub(crate) mod quic;
35#[cfg(feature = "std")]
36pub(crate) mod ticketer;
37pub(crate) mod tls12;
38pub(crate) mod tls13;
39
40/// A `CryptoProvider` backed by aws-lc-rs.
41pub fn default_provider() -> CryptoProvider {
42    CryptoProvider {
43        cipher_suites: DEFAULT_CIPHER_SUITES.to_vec(),
44        kx_groups: default_kx_groups(),
45        signature_verification_algorithms: SUPPORTED_SIG_ALGS,
46        secure_random: &AwsLcRs,
47        key_provider: &AwsLcRs,
48    }
49}
50
51fn default_kx_groups() -> Vec<&'static dyn SupportedKxGroup> {
52    #[cfg(feature = "fips")]
53    {
54        DEFAULT_KX_GROUPS
55            .iter()
56            .filter(|cs| cs.fips())
57            .copied()
58            .collect()
59    }
60    #[cfg(not(feature = "fips"))]
61    {
62        DEFAULT_KX_GROUPS.to_vec()
63    }
64}
65
66/// `KeyProvider` impl for aws-lc-rs
67pub static DEFAULT_KEY_PROVIDER: &dyn KeyProvider = &AwsLcRs;
68
69/// `SecureRandom` impl for aws-lc-rs
70pub static DEFAULT_SECURE_RANDOM: &dyn SecureRandom = &AwsLcRs;
71
72#[derive(Debug)]
73struct AwsLcRs;
74
75impl SecureRandom for AwsLcRs {
76    fn fill(&self, buf: &mut [u8]) -> Result<(), GetRandomFailed> {
77        use ring_like::rand::SecureRandom;
78
79        ring_like::rand::SystemRandom::new()
80            .fill(buf)
81            .map_err(|_| GetRandomFailed)
82    }
83
84    fn fips(&self) -> bool {
85        fips()
86    }
87}
88
89impl KeyProvider for AwsLcRs {
90    fn load_private_key(
91        &self,
92        key_der: PrivateKeyDer<'static>,
93    ) -> Result<Arc<dyn SigningKey>, Error> {
94        sign::any_supported_type(&key_der)
95    }
96
97    fn fips(&self) -> bool {
98        fips()
99    }
100}
101
102/// The cipher suite configuration that an application should use by default.
103///
104/// This will be [`ALL_CIPHER_SUITES`] sans any supported cipher suites that
105/// shouldn't be enabled by most applications.
106pub static DEFAULT_CIPHER_SUITES: &[SupportedCipherSuite] = &[
107    // TLS1.3 suites
108    tls13::TLS13_AES_256_GCM_SHA384,
109    tls13::TLS13_AES_128_GCM_SHA256,
110    #[cfg(not(feature = "fips"))]
111    tls13::TLS13_CHACHA20_POLY1305_SHA256,
112    // TLS1.2 suites
113    tls12::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
114    tls12::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
115    #[cfg(not(feature = "fips"))]
116    tls12::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
117    tls12::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
118    tls12::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
119    #[cfg(not(feature = "fips"))]
120    tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
121];
122
123/// A list of all the cipher suites supported by the rustls aws-lc-rs provider.
124pub static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = &[
125    // TLS1.3 suites
126    tls13::TLS13_AES_256_GCM_SHA384,
127    tls13::TLS13_AES_128_GCM_SHA256,
128    tls13::TLS13_CHACHA20_POLY1305_SHA256,
129    // TLS1.2 suites
130    tls12::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
131    tls12::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
132    tls12::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
133    tls12::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
134    tls12::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
135    tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
136];
137
138/// All defined cipher suites supported by aws-lc-rs appear in this module.
139pub mod cipher_suite {
140    pub use super::tls12::{
141        TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
142        TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
143        TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
144    };
145    pub use super::tls13::{
146        TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384, TLS13_CHACHA20_POLY1305_SHA256,
147    };
148}
149
150/// A `WebPkiSupportedAlgorithms` value that reflects webpki's capabilities when
151/// compiled against aws-lc-rs.
152pub static SUPPORTED_SIG_ALGS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms {
153    all: &[
154        webpki_algs::ECDSA_P256_SHA256,
155        webpki_algs::ECDSA_P256_SHA384,
156        webpki_algs::ECDSA_P384_SHA256,
157        webpki_algs::ECDSA_P384_SHA384,
158        webpki_algs::ECDSA_P521_SHA256,
159        webpki_algs::ECDSA_P521_SHA384,
160        webpki_algs::ECDSA_P521_SHA512,
161        webpki_algs::ED25519,
162        webpki_algs::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
163        webpki_algs::RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
164        webpki_algs::RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
165        webpki_algs::RSA_PKCS1_2048_8192_SHA256,
166        webpki_algs::RSA_PKCS1_2048_8192_SHA384,
167        webpki_algs::RSA_PKCS1_2048_8192_SHA512,
168        webpki_algs::RSA_PKCS1_2048_8192_SHA256_ABSENT_PARAMS,
169        webpki_algs::RSA_PKCS1_2048_8192_SHA384_ABSENT_PARAMS,
170        webpki_algs::RSA_PKCS1_2048_8192_SHA512_ABSENT_PARAMS,
171    ],
172    mapping: &[
173        // Note: for TLS1.2 the curve is not fixed by SignatureScheme. For TLS1.3 it is.
174        (
175            SignatureScheme::ECDSA_NISTP384_SHA384,
176            &[
177                webpki_algs::ECDSA_P384_SHA384,
178                webpki_algs::ECDSA_P256_SHA384,
179                webpki_algs::ECDSA_P521_SHA384,
180            ],
181        ),
182        (
183            SignatureScheme::ECDSA_NISTP256_SHA256,
184            &[
185                webpki_algs::ECDSA_P256_SHA256,
186                webpki_algs::ECDSA_P384_SHA256,
187                webpki_algs::ECDSA_P521_SHA256,
188            ],
189        ),
190        (
191            SignatureScheme::ECDSA_NISTP521_SHA512,
192            &[webpki_algs::ECDSA_P521_SHA512],
193        ),
194        (SignatureScheme::ED25519, &[webpki_algs::ED25519]),
195        (
196            SignatureScheme::RSA_PSS_SHA512,
197            &[webpki_algs::RSA_PSS_2048_8192_SHA512_LEGACY_KEY],
198        ),
199        (
200            SignatureScheme::RSA_PSS_SHA384,
201            &[webpki_algs::RSA_PSS_2048_8192_SHA384_LEGACY_KEY],
202        ),
203        (
204            SignatureScheme::RSA_PSS_SHA256,
205            &[webpki_algs::RSA_PSS_2048_8192_SHA256_LEGACY_KEY],
206        ),
207        (
208            SignatureScheme::RSA_PKCS1_SHA512,
209            &[webpki_algs::RSA_PKCS1_2048_8192_SHA512],
210        ),
211        (
212            SignatureScheme::RSA_PKCS1_SHA384,
213            &[webpki_algs::RSA_PKCS1_2048_8192_SHA384],
214        ),
215        (
216            SignatureScheme::RSA_PKCS1_SHA256,
217            &[webpki_algs::RSA_PKCS1_2048_8192_SHA256],
218        ),
219    ],
220};
221
222/// All defined key exchange groups supported by aws-lc-rs appear in this module.
223///
224/// [`ALL_KX_GROUPS`] is provided as an array of all of these values.
225/// [`DEFAULT_KX_GROUPS`] is provided as an array of this provider's defaults.
226pub mod kx_group {
227    pub use super::kx::{SECP256R1, SECP384R1, X25519};
228    pub use super::pq::{MLKEM768, SECP256R1MLKEM768, X25519MLKEM768};
229}
230
231/// A list of the default key exchange groups supported by this provider.
232///
233/// This does not contain MLKEM768; by default MLKEM768 is only offered
234/// in hybrid with X25519.
235pub static DEFAULT_KX_GROUPS: &[&dyn SupportedKxGroup] = &[
236    kx_group::X25519MLKEM768,
237    kx_group::X25519,
238    kx_group::SECP256R1,
239    kx_group::SECP384R1,
240];
241
242/// A list of all the key exchange groups supported by this provider.
243pub static ALL_KX_GROUPS: &[&dyn SupportedKxGroup] = &[
244    kx_group::X25519MLKEM768,
245    kx_group::SECP256R1MLKEM768,
246    kx_group::X25519,
247    kx_group::SECP256R1,
248    kx_group::SECP384R1,
249    kx_group::MLKEM768,
250];
251
252#[cfg(feature = "std")]
253pub use ticketer::Ticketer;
254
255/// Compatibility shims between ring 0.16.x and 0.17.x API
256mod ring_shim {
257    use super::ring_like;
258    use crate::crypto::SharedSecret;
259
260    pub(super) fn agree_ephemeral(
261        priv_key: ring_like::agreement::EphemeralPrivateKey,
262        peer_key: &ring_like::agreement::UnparsedPublicKey<&[u8]>,
263    ) -> Result<SharedSecret, ()> {
264        ring_like::agreement::agree_ephemeral(priv_key, peer_key, (), |secret| {
265            Ok(SharedSecret::from(secret))
266        })
267    }
268}
269
270/// Are we in FIPS mode?
271pub(super) fn fips() -> bool {
272    aws_lc_rs::try_fips_mode().is_ok()
273}
274
275pub(super) fn unspecified_err(_e: aws_lc_rs::error::Unspecified) -> Error {
276    #[cfg(feature = "std")]
277    {
278        Error::Other(OtherError(Arc::new(_e)))
279    }
280    #[cfg(not(feature = "std"))]
281    {
282        Error::Other(OtherError())
283    }
284}
285
286#[cfg(test)]
287mod tests {
288    #[cfg(feature = "fips")]
289    #[test]
290    fn default_suites_are_fips() {
291        assert!(
292            super::DEFAULT_CIPHER_SUITES
293                .iter()
294                .all(|scs| scs.fips())
295        );
296    }
297
298    #[cfg(not(feature = "fips"))]
299    #[test]
300    fn default_suites() {
301        assert_eq!(super::DEFAULT_CIPHER_SUITES, super::ALL_CIPHER_SUITES);
302    }
303}