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