portable_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(any(feature = "std", feature = "hashbrown"))]
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    // [FIPS REMOVED FROM THIS FORK]
54    // #[cfg(... "fips")]
55    // ...
56    // [FIPS REMOVED FROM THIS FORK] #[cfg(not(... "fips"))]
57    {
58        DEFAULT_KX_GROUPS.to_vec()
59    }
60}
61
62#[derive(Debug)]
63struct AwsLcRs;
64
65impl SecureRandom for AwsLcRs {
66    fn fill(&self, buf: &mut [u8]) -> Result<(), GetRandomFailed> {
67        use ring_like::rand::SecureRandom;
68
69        ring_like::rand::SystemRandom::new()
70            .fill(buf)
71            .map_err(|_| GetRandomFailed)
72    }
73
74    #[cfg(unstable_api_not_supported)] // [FIPS REMOVED FROM THIS FORK]
75    fn fips(&self) -> bool {
76        fips()
77    }
78}
79
80impl KeyProvider for AwsLcRs {
81    fn load_private_key(
82        &self,
83        key_der: PrivateKeyDer<'static>,
84    ) -> Result<Arc<dyn SigningKey>, Error> {
85        sign::any_supported_type(&key_der)
86    }
87
88    #[cfg(unstable_api_not_supported)] // [FIPS REMOVED FROM THIS FORK]
89    fn fips(&self) -> bool {
90        fips()
91    }
92}
93
94/// The cipher suite configuration that an application should use by default.
95///
96/// This will be [`ALL_CIPHER_SUITES`] sans any supported cipher suites that
97/// shouldn't be enabled by most applications.
98pub static DEFAULT_CIPHER_SUITES: &[SupportedCipherSuite] = &[
99    // TLS1.3 suites
100    tls13::TLS13_AES_256_GCM_SHA384,
101    tls13::TLS13_AES_128_GCM_SHA256,
102    // [FIPS REMOVED FROM THIS FORK] #[cfg(not(... "fips"))]
103    tls13::TLS13_CHACHA20_POLY1305_SHA256,
104    // TLS1.2 suites
105    #[cfg(feature = "tls12")]
106    tls12::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
107    #[cfg(feature = "tls12")]
108    tls12::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
109    // [FIPS REMOVED FROM THIS FORK]
110    // #[cfg(all(..., not(... "fips")))]
111    #[cfg(feature = "tls12")]
112    tls12::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
113    #[cfg(feature = "tls12")]
114    tls12::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
115    #[cfg(feature = "tls12")]
116    tls12::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
117    // [FIPS REMOVED FROM THIS FORK]
118    // #[cfg(all(..., not(... "fips")))]
119    #[cfg(feature = "tls12")]
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_P384_SHA256,
164        webpki_algs::ECDSA_P384_SHA384,
165        webpki_algs::ECDSA_P521_SHA256,
166        webpki_algs::ECDSA_P521_SHA384,
167        webpki_algs::ECDSA_P521_SHA512,
168        webpki_algs::ED25519,
169        webpki_algs::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
170        webpki_algs::RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
171        webpki_algs::RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
172        webpki_algs::RSA_PKCS1_2048_8192_SHA256,
173        webpki_algs::RSA_PKCS1_2048_8192_SHA384,
174        webpki_algs::RSA_PKCS1_2048_8192_SHA512,
175        webpki_algs::RSA_PKCS1_3072_8192_SHA384,
176    ],
177    mapping: &[
178        // Note: for TLS1.2 the curve is not fixed by SignatureScheme. For TLS1.3 it is.
179        (
180            SignatureScheme::ECDSA_NISTP384_SHA384,
181            &[
182                webpki_algs::ECDSA_P384_SHA384,
183                webpki_algs::ECDSA_P256_SHA384,
184                webpki_algs::ECDSA_P521_SHA384,
185            ],
186        ),
187        (
188            SignatureScheme::ECDSA_NISTP256_SHA256,
189            &[
190                webpki_algs::ECDSA_P256_SHA256,
191                webpki_algs::ECDSA_P384_SHA256,
192                webpki_algs::ECDSA_P521_SHA256,
193            ],
194        ),
195        (
196            SignatureScheme::ECDSA_NISTP521_SHA512,
197            &[webpki_algs::ECDSA_P521_SHA512],
198        ),
199        (SignatureScheme::ED25519, &[webpki_algs::ED25519]),
200        (
201            SignatureScheme::RSA_PSS_SHA512,
202            &[webpki_algs::RSA_PSS_2048_8192_SHA512_LEGACY_KEY],
203        ),
204        (
205            SignatureScheme::RSA_PSS_SHA384,
206            &[webpki_algs::RSA_PSS_2048_8192_SHA384_LEGACY_KEY],
207        ),
208        (
209            SignatureScheme::RSA_PSS_SHA256,
210            &[webpki_algs::RSA_PSS_2048_8192_SHA256_LEGACY_KEY],
211        ),
212        (
213            SignatureScheme::RSA_PKCS1_SHA512,
214            &[webpki_algs::RSA_PKCS1_2048_8192_SHA512],
215        ),
216        (
217            SignatureScheme::RSA_PKCS1_SHA384,
218            &[webpki_algs::RSA_PKCS1_2048_8192_SHA384],
219        ),
220        (
221            SignatureScheme::RSA_PKCS1_SHA256,
222            &[webpki_algs::RSA_PKCS1_2048_8192_SHA256],
223        ),
224    ],
225};
226
227/// All defined key exchange groups supported by aws-lc-rs appear in this module.
228///
229/// [`ALL_KX_GROUPS`] is provided as an array of all of these values.
230/// [`DEFAULT_KX_GROUPS`] is provided as an array of this provider's defaults.
231pub mod kx_group {
232    pub use super::kx::{SECP256R1, SECP384R1, X25519};
233    pub use super::pq::{MLKEM768, X25519MLKEM768};
234}
235
236/// A list of the default key exchange groups supported by this provider.
237///
238/// This does not contain MLKEM768; by default MLKEM768 is only offered
239/// in hybrid with X25519.
240pub static DEFAULT_KX_GROUPS: &[&dyn SupportedKxGroup] = &[
241    #[cfg(feature = "prefer-post-quantum")]
242    kx_group::X25519MLKEM768,
243    kx_group::X25519,
244    kx_group::SECP256R1,
245    kx_group::SECP384R1,
246    #[cfg(not(feature = "prefer-post-quantum"))]
247    kx_group::X25519MLKEM768,
248];
249
250/// A list of all the key exchange groups supported by this provider.
251pub static ALL_KX_GROUPS: &[&dyn SupportedKxGroup] = &[
252    #[cfg(feature = "prefer-post-quantum")]
253    kx_group::X25519MLKEM768,
254    kx_group::X25519,
255    kx_group::SECP256R1,
256    kx_group::SECP384R1,
257    #[cfg(not(feature = "prefer-post-quantum"))]
258    kx_group::X25519MLKEM768,
259    kx_group::MLKEM768,
260];
261
262#[cfg(any(feature = "std", feature = "hashbrown"))]
263pub use ticketer::Ticketer;
264
265/// Compatibility shims between ring 0.16.x and 0.17.x API
266mod ring_shim {
267    use super::ring_like;
268    use crate::crypto::SharedSecret;
269
270    pub(super) fn agree_ephemeral(
271        priv_key: ring_like::agreement::EphemeralPrivateKey,
272        peer_key: &ring_like::agreement::UnparsedPublicKey<&[u8]>,
273    ) -> Result<SharedSecret, ()> {
274        ring_like::agreement::agree_ephemeral(priv_key, peer_key, (), |secret| {
275            Ok(SharedSecret::from(secret))
276        })
277    }
278}
279
280/// Are we in FIPS mode?
281#[cfg(unstable_api_not_supported)] // [FIPS REMOVED FROM THIS FORK]
282pub(super) fn fips() -> bool {
283    aws_lc_rs::try_fips_mode().is_ok()
284}
285
286pub(super) fn unspecified_err(_e: aws_lc_rs::error::Unspecified) -> Error {
287    #[cfg(feature = "std")]
288    {
289        Error::Other(OtherError(Arc::new(_e)))
290    }
291    #[cfg(not(feature = "std"))]
292    {
293        Error::Other(OtherError())
294    }
295}
296
297#[cfg(test)]
298mod tests {
299    // [FIPS REMOVED FROM THIS FORK]
300    // #[cfg(... "fips")]
301    // #[test]
302    // fn default_suites_are_fips() ...
303
304    // [FIPS REMOVED FROM THIS FORK] #[cfg(not(... "fips"))]
305    #[test]
306    fn default_suites() {
307        assert_eq!(super::DEFAULT_CIPHER_SUITES, super::ALL_CIPHER_SUITES);
308    }
309}