rustls/crypto/aws_lc_rs/
mod.rs

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