Skip to main content

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;
37#[cfg(feature = "tls12")]
38pub(crate) mod tls12;
39pub(crate) mod tls13;
40
41/// A `CryptoProvider` backed by aws-lc-rs.
42pub fn default_provider() -> CryptoProvider {
43    CryptoProvider {
44        cipher_suites: DEFAULT_CIPHER_SUITES.to_vec(),
45        kx_groups: default_kx_groups(),
46        signature_verification_algorithms: SUPPORTED_SIG_ALGS,
47        secure_random: &AwsLcRs,
48        key_provider: &AwsLcRs,
49    }
50}
51
52fn default_kx_groups() -> Vec<&'static dyn SupportedKxGroup> {
53    #[cfg(feature = "fips")]
54    {
55        DEFAULT_KX_GROUPS
56            .iter()
57            .filter(|cs| cs.fips())
58            .copied()
59            .collect()
60    }
61    #[cfg(not(feature = "fips"))]
62    {
63        DEFAULT_KX_GROUPS.to_vec()
64    }
65}
66
67#[derive(Debug)]
68struct AwsLcRs;
69
70impl SecureRandom for AwsLcRs {
71    fn fill(&self, buf: &mut [u8]) -> Result<(), GetRandomFailed> {
72        use ring_like::rand::SecureRandom;
73
74        ring_like::rand::SystemRandom::new()
75            .fill(buf)
76            .map_err(|_| GetRandomFailed)
77    }
78
79    fn fips(&self) -> bool {
80        fips()
81    }
82}
83
84impl KeyProvider for AwsLcRs {
85    fn load_private_key(
86        &self,
87        key_der: PrivateKeyDer<'static>,
88    ) -> Result<Arc<dyn SigningKey>, Error> {
89        sign::any_supported_type(&key_der)
90    }
91
92    fn fips(&self) -> bool {
93        fips()
94    }
95}
96
97/// The cipher suite configuration that an application should use by default.
98///
99/// This will be [`ALL_CIPHER_SUITES`] sans any supported cipher suites that
100/// shouldn't be enabled by most applications.
101pub static DEFAULT_CIPHER_SUITES: &[SupportedCipherSuite] = &[
102    // TLS1.3 suites
103    tls13::TLS13_AES_256_GCM_SHA384,
104    tls13::TLS13_AES_128_GCM_SHA256,
105    #[cfg(not(feature = "fips"))]
106    tls13::TLS13_CHACHA20_POLY1305_SHA256,
107    // TLS1.2 suites
108    #[cfg(feature = "tls12")]
109    tls12::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
110    #[cfg(feature = "tls12")]
111    tls12::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
112    #[cfg(all(feature = "tls12", not(feature = "fips")))]
113    tls12::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
114    #[cfg(feature = "tls12")]
115    tls12::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
116    #[cfg(feature = "tls12")]
117    tls12::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
118    #[cfg(all(feature = "tls12", not(feature = "fips")))]
119    tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
120];
121
122/// A list of all the cipher suites supported by the rustls aws-lc-rs provider.
123pub static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = &[
124    // TLS1.3 suites
125    tls13::TLS13_AES_256_GCM_SHA384,
126    tls13::TLS13_AES_128_GCM_SHA256,
127    tls13::TLS13_CHACHA20_POLY1305_SHA256,
128    // TLS1.2 suites
129    #[cfg(feature = "tls12")]
130    tls12::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
131    #[cfg(feature = "tls12")]
132    tls12::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
133    #[cfg(feature = "tls12")]
134    tls12::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
135    #[cfg(feature = "tls12")]
136    tls12::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
137    #[cfg(feature = "tls12")]
138    tls12::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
139    #[cfg(feature = "tls12")]
140    tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
141];
142
143/// All defined cipher suites supported by aws-lc-rs appear in this module.
144pub mod cipher_suite {
145    #[cfg(feature = "tls12")]
146    pub use super::tls12::{
147        TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
148        TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
149        TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
150    };
151    pub use super::tls13::{
152        TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384, TLS13_CHACHA20_POLY1305_SHA256,
153    };
154}
155
156/// A `WebPkiSupportedAlgorithms` value that reflects webpki's capabilities when
157/// compiled against aws-lc-rs.
158static SUPPORTED_SIG_ALGS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms {
159    all: &[
160        webpki_algs::ECDSA_P256_SHA256,
161        webpki_algs::ECDSA_P256_SHA384,
162        webpki_algs::ECDSA_P256_SHA512,
163        webpki_algs::ECDSA_P384_SHA256,
164        webpki_algs::ECDSA_P384_SHA384,
165        webpki_algs::ECDSA_P384_SHA512,
166        webpki_algs::ECDSA_P521_SHA256,
167        webpki_algs::ECDSA_P521_SHA384,
168        webpki_algs::ECDSA_P521_SHA512,
169        webpki_algs::ED25519,
170        webpki_algs::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
171        webpki_algs::RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
172        webpki_algs::RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
173        webpki_algs::RSA_PKCS1_2048_8192_SHA256,
174        webpki_algs::RSA_PKCS1_2048_8192_SHA384,
175        webpki_algs::RSA_PKCS1_2048_8192_SHA512,
176        webpki_algs::RSA_PKCS1_2048_8192_SHA256_ABSENT_PARAMS,
177        webpki_algs::RSA_PKCS1_2048_8192_SHA384_ABSENT_PARAMS,
178        webpki_algs::RSA_PKCS1_2048_8192_SHA512_ABSENT_PARAMS,
179        webpki_algs::ML_DSA_44,
180        webpki_algs::ML_DSA_65,
181        webpki_algs::ML_DSA_87,
182    ],
183    mapping: &[
184        // Note: for TLS1.2 the curve is not fixed by SignatureScheme. For TLS1.3 it is.
185        (
186            SignatureScheme::ECDSA_NISTP384_SHA384,
187            &[
188                webpki_algs::ECDSA_P384_SHA384,
189                webpki_algs::ECDSA_P256_SHA384,
190                webpki_algs::ECDSA_P521_SHA384,
191            ],
192        ),
193        (
194            SignatureScheme::ECDSA_NISTP256_SHA256,
195            &[
196                webpki_algs::ECDSA_P256_SHA256,
197                webpki_algs::ECDSA_P384_SHA256,
198                webpki_algs::ECDSA_P521_SHA256,
199            ],
200        ),
201        (
202            SignatureScheme::ECDSA_NISTP521_SHA512,
203            &[
204                webpki_algs::ECDSA_P521_SHA512,
205                webpki_algs::ECDSA_P384_SHA512,
206                webpki_algs::ECDSA_P256_SHA512,
207            ],
208        ),
209        (SignatureScheme::ED25519, &[webpki_algs::ED25519]),
210        (
211            SignatureScheme::RSA_PSS_SHA512,
212            &[webpki_algs::RSA_PSS_2048_8192_SHA512_LEGACY_KEY],
213        ),
214        (
215            SignatureScheme::RSA_PSS_SHA384,
216            &[webpki_algs::RSA_PSS_2048_8192_SHA384_LEGACY_KEY],
217        ),
218        (
219            SignatureScheme::RSA_PSS_SHA256,
220            &[webpki_algs::RSA_PSS_2048_8192_SHA256_LEGACY_KEY],
221        ),
222        (
223            SignatureScheme::RSA_PKCS1_SHA512,
224            &[webpki_algs::RSA_PKCS1_2048_8192_SHA512],
225        ),
226        (
227            SignatureScheme::RSA_PKCS1_SHA384,
228            &[webpki_algs::RSA_PKCS1_2048_8192_SHA384],
229        ),
230        (
231            SignatureScheme::RSA_PKCS1_SHA256,
232            &[webpki_algs::RSA_PKCS1_2048_8192_SHA256],
233        ),
234        (SignatureScheme::ML_DSA_44, &[webpki_algs::ML_DSA_44]),
235        (SignatureScheme::ML_DSA_65, &[webpki_algs::ML_DSA_65]),
236        (SignatureScheme::ML_DSA_87, &[webpki_algs::ML_DSA_87]),
237    ],
238};
239
240/// All defined key exchange groups supported by aws-lc-rs appear in this module.
241///
242/// [`ALL_KX_GROUPS`] is provided as an array of all of these values.
243/// [`DEFAULT_KX_GROUPS`] is provided as an array of this provider's defaults.
244pub mod kx_group {
245    pub use super::kx::{SECP256R1, SECP384R1, X25519};
246    pub use super::pq::{MLKEM768, MLKEM1024, SECP256R1MLKEM768, X25519MLKEM768};
247}
248
249/// A list of the default key exchange groups supported by this provider.
250///
251/// This does not contain MLKEM768; by default MLKEM768 is only offered
252/// in hybrid with X25519.
253pub static DEFAULT_KX_GROUPS: &[&dyn SupportedKxGroup] = &[
254    #[cfg(feature = "prefer-post-quantum")]
255    kx_group::X25519MLKEM768,
256    kx_group::X25519,
257    kx_group::SECP256R1,
258    kx_group::SECP384R1,
259    #[cfg(not(feature = "prefer-post-quantum"))]
260    kx_group::X25519MLKEM768,
261];
262
263/// A list of all the key exchange groups supported by this provider.
264pub static ALL_KX_GROUPS: &[&dyn SupportedKxGroup] = &[
265    #[cfg(feature = "prefer-post-quantum")]
266    kx_group::X25519MLKEM768,
267    #[cfg(feature = "prefer-post-quantum")]
268    kx_group::SECP256R1MLKEM768,
269    kx_group::X25519,
270    kx_group::SECP256R1,
271    kx_group::SECP384R1,
272    #[cfg(not(feature = "prefer-post-quantum"))]
273    kx_group::X25519MLKEM768,
274    #[cfg(not(feature = "prefer-post-quantum"))]
275    kx_group::SECP256R1MLKEM768,
276    kx_group::MLKEM768,
277    kx_group::MLKEM1024,
278];
279
280#[cfg(feature = "std")]
281pub use ticketer::Ticketer;
282
283/// Compatibility shims between ring 0.16.x and 0.17.x API
284mod ring_shim {
285    use super::ring_like;
286    use crate::crypto::SharedSecret;
287
288    pub(super) fn agree_ephemeral(
289        priv_key: ring_like::agreement::EphemeralPrivateKey,
290        peer_key: &ring_like::agreement::UnparsedPublicKey<&[u8]>,
291    ) -> Result<SharedSecret, ()> {
292        ring_like::agreement::agree_ephemeral(priv_key, peer_key, (), |secret| {
293            Ok(SharedSecret::from(secret))
294        })
295    }
296}
297
298/// Are we in FIPS mode?
299pub(super) fn fips() -> bool {
300    aws_lc_rs::try_fips_mode().is_ok()
301}
302
303pub(super) fn unspecified_err(_e: aws_lc_rs::error::Unspecified) -> Error {
304    #[cfg(feature = "std")]
305    {
306        Error::Other(OtherError(Arc::new(_e)))
307    }
308    #[cfg(not(feature = "std"))]
309    {
310        Error::Other(OtherError())
311    }
312}
313
314#[cfg(test)]
315mod tests {
316    use std::collections::HashSet;
317
318    #[cfg(feature = "fips")]
319    #[test]
320    fn default_suites_are_fips() {
321        assert!(
322            super::DEFAULT_CIPHER_SUITES
323                .iter()
324                .all(|scs| scs.fips())
325        );
326    }
327
328    #[cfg(not(feature = "fips"))]
329    #[test]
330    fn default_suites() {
331        assert_eq!(super::DEFAULT_CIPHER_SUITES, super::ALL_CIPHER_SUITES);
332    }
333
334    #[test]
335    fn certificate_sig_algs() {
336        // `all` should not contain duplicates (not incorrect, but a waste of time)
337        assert_eq!(
338            super::SUPPORTED_SIG_ALGS
339                .all
340                .iter()
341                .map(|alg| {
342                    (
343                        alg.public_key_alg_id()
344                            .as_ref()
345                            .to_vec(),
346                        alg.signature_alg_id().as_ref().to_vec(),
347                    )
348                })
349                .collect::<HashSet<_>>()
350                .len(),
351            super::SUPPORTED_SIG_ALGS.all.len(),
352        );
353    }
354}