1use alloc::borrow::Cow;
2use alloc::boxed::Box;
3
4use pki_types::PrivateKeyDer;
5use webpki::aws_lc_rs as webpki_algs;
6
7use super::signer::SigningKey;
8use crate::crypto::{
9 CryptoProvider, GetRandomFailed, KeyProvider, SecureRandom, SignatureScheme, SupportedKxGroup,
10 TicketProducer, TicketerFactory,
11};
12use crate::error::{Error, OtherError};
13use crate::sync::Arc;
14#[cfg(feature = "std")]
15use crate::ticketer::TicketRotator;
16use crate::tls12::Tls12CipherSuite;
17use crate::tls13::Tls13CipherSuite;
18use crate::webpki::WebPkiSupportedAlgorithms;
19
20pub mod hpke;
22pub(crate) mod pq;
24pub mod sign;
26use sign::{EcdsaSigner, Ed25519Signer, RsaSigningKey};
27
28pub(crate) mod hash;
29pub(crate) mod hmac;
30pub(crate) mod kx;
31pub(crate) mod quic;
32#[cfg(feature = "std")]
33pub(crate) mod ticketer;
34#[cfg(feature = "std")]
35use ticketer::Rfc5077Ticketer;
36pub(crate) mod tls12;
37pub(crate) mod tls13;
38
39pub const DEFAULT_PROVIDER: CryptoProvider = CryptoProvider {
41 tls12_cipher_suites: Cow::Borrowed(DEFAULT_TLS12_CIPHER_SUITES),
42 tls13_cipher_suites: Cow::Borrowed(DEFAULT_TLS13_CIPHER_SUITES),
43 kx_groups: Cow::Borrowed(DEFAULT_KX_GROUPS),
44 signature_verification_algorithms: SUPPORTED_SIG_ALGS,
45 secure_random: &AwsLcRs,
46 key_provider: &AwsLcRs,
47 ticketer_factory: &AwsLcRs,
48};
49
50pub const DEFAULT_TLS13_PROVIDER: CryptoProvider = CryptoProvider {
52 tls12_cipher_suites: Cow::Borrowed(&[]),
53 ..DEFAULT_PROVIDER
54};
55
56pub const DEFAULT_TLS12_PROVIDER: CryptoProvider = CryptoProvider {
60 tls13_cipher_suites: Cow::Borrowed(&[]),
61 ..DEFAULT_PROVIDER
62};
63
64pub static DEFAULT_KEY_PROVIDER: &dyn KeyProvider = &AwsLcRs;
66
67pub static DEFAULT_SECURE_RANDOM: &dyn SecureRandom = &AwsLcRs;
69
70#[derive(Debug)]
71struct AwsLcRs;
72
73impl SecureRandom for AwsLcRs {
74 fn fill(&self, buf: &mut [u8]) -> Result<(), GetRandomFailed> {
75 use aws_lc_rs::rand::SecureRandom;
76
77 aws_lc_rs::rand::SystemRandom::new()
78 .fill(buf)
79 .map_err(|_| GetRandomFailed)
80 }
81
82 fn fips(&self) -> bool {
83 fips()
84 }
85}
86
87impl KeyProvider for AwsLcRs {
88 fn load_private_key(
89 &self,
90 key_der: PrivateKeyDer<'static>,
91 ) -> Result<Box<dyn SigningKey>, Error> {
92 if let Ok(rsa) = RsaSigningKey::try_from(&key_der) {
93 return Ok(Box::new(rsa));
94 }
95
96 if let Ok(ecdsa) = EcdsaSigner::try_from(&key_der) {
97 return Ok(Box::new(ecdsa));
98 }
99
100 if let PrivateKeyDer::Pkcs8(pkcs8) = key_der {
101 if let Ok(eddsa) = Ed25519Signer::try_from(&pkcs8) {
102 return Ok(Box::new(eddsa));
103 }
104 }
105
106 Err(Error::General(
107 "failed to parse private key as RSA, ECDSA, or EdDSA".into(),
108 ))
109 }
110
111 fn fips(&self) -> bool {
112 fips()
113 }
114}
115
116impl TicketerFactory for AwsLcRs {
117 fn ticketer(&self) -> Result<Arc<dyn TicketProducer>, Error> {
130 #[cfg(feature = "std")]
131 {
132 Ok(Arc::new(TicketRotator::new(
133 TicketRotator::SIX_HOURS,
134 Rfc5077Ticketer::new,
135 )?))
136 }
137 #[cfg(not(feature = "std"))]
138 {
139 Err(Error::General(
140 "AwsLcRs::ticketer() relies on std-only RwLock via TicketRotator".into(),
141 ))
142 }
143 }
144
145 fn fips(&self) -> bool {
146 fips()
147 }
148}
149
150pub static DEFAULT_TLS12_CIPHER_SUITES: &[&Tls12CipherSuite] = &[
155 tls12::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
156 tls12::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
157 #[cfg(not(feature = "fips"))]
158 tls12::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
159 tls12::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
160 tls12::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
161 #[cfg(not(feature = "fips"))]
162 tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
163];
164
165pub static DEFAULT_TLS13_CIPHER_SUITES: &[&Tls13CipherSuite] = &[
170 tls13::TLS13_AES_256_GCM_SHA384,
171 tls13::TLS13_AES_128_GCM_SHA256,
172 #[cfg(not(feature = "fips"))]
173 tls13::TLS13_CHACHA20_POLY1305_SHA256,
174];
175
176pub static ALL_TLS12_CIPHER_SUITES: &[&Tls12CipherSuite] = &[
178 tls12::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
179 tls12::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
180 tls12::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
181 tls12::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
182 tls12::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
183 tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
184];
185
186pub static ALL_TLS13_CIPHER_SUITES: &[&Tls13CipherSuite] = &[
188 tls13::TLS13_AES_256_GCM_SHA384,
189 tls13::TLS13_AES_128_GCM_SHA256,
190 tls13::TLS13_CHACHA20_POLY1305_SHA256,
191];
192
193pub mod cipher_suite {
195 pub use super::tls12::{
196 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
197 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
198 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
199 };
200 pub use super::tls13::{
201 TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384, TLS13_CHACHA20_POLY1305_SHA256,
202 };
203}
204
205pub static SUPPORTED_SIG_ALGS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms {
208 all: &[
209 webpki_algs::ECDSA_P256_SHA256,
210 webpki_algs::ECDSA_P256_SHA384,
211 webpki_algs::ECDSA_P384_SHA256,
212 webpki_algs::ECDSA_P384_SHA384,
213 webpki_algs::ECDSA_P521_SHA256,
214 webpki_algs::ECDSA_P521_SHA384,
215 webpki_algs::ECDSA_P521_SHA512,
216 webpki_algs::ED25519,
217 webpki_algs::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
218 webpki_algs::RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
219 webpki_algs::RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
220 webpki_algs::RSA_PKCS1_2048_8192_SHA256,
221 webpki_algs::RSA_PKCS1_2048_8192_SHA384,
222 webpki_algs::RSA_PKCS1_2048_8192_SHA512,
223 webpki_algs::RSA_PKCS1_2048_8192_SHA256_ABSENT_PARAMS,
224 webpki_algs::RSA_PKCS1_2048_8192_SHA384_ABSENT_PARAMS,
225 webpki_algs::RSA_PKCS1_2048_8192_SHA512_ABSENT_PARAMS,
226 ],
227 mapping: &[
228 (
230 SignatureScheme::ECDSA_NISTP384_SHA384,
231 &[
232 webpki_algs::ECDSA_P384_SHA384,
233 webpki_algs::ECDSA_P256_SHA384,
234 webpki_algs::ECDSA_P521_SHA384,
235 ],
236 ),
237 (
238 SignatureScheme::ECDSA_NISTP256_SHA256,
239 &[
240 webpki_algs::ECDSA_P256_SHA256,
241 webpki_algs::ECDSA_P384_SHA256,
242 webpki_algs::ECDSA_P521_SHA256,
243 ],
244 ),
245 (
246 SignatureScheme::ECDSA_NISTP521_SHA512,
247 &[
248 webpki_algs::ECDSA_P521_SHA512,
249 webpki_algs::ECDSA_P384_SHA512,
250 webpki_algs::ECDSA_P256_SHA512,
251 ],
252 ),
253 (SignatureScheme::ED25519, &[webpki_algs::ED25519]),
254 (
255 SignatureScheme::RSA_PSS_SHA512,
256 &[webpki_algs::RSA_PSS_2048_8192_SHA512_LEGACY_KEY],
257 ),
258 (
259 SignatureScheme::RSA_PSS_SHA384,
260 &[webpki_algs::RSA_PSS_2048_8192_SHA384_LEGACY_KEY],
261 ),
262 (
263 SignatureScheme::RSA_PSS_SHA256,
264 &[webpki_algs::RSA_PSS_2048_8192_SHA256_LEGACY_KEY],
265 ),
266 (
267 SignatureScheme::RSA_PKCS1_SHA512,
268 &[webpki_algs::RSA_PKCS1_2048_8192_SHA512],
269 ),
270 (
271 SignatureScheme::RSA_PKCS1_SHA384,
272 &[webpki_algs::RSA_PKCS1_2048_8192_SHA384],
273 ),
274 (
275 SignatureScheme::RSA_PKCS1_SHA256,
276 &[webpki_algs::RSA_PKCS1_2048_8192_SHA256],
277 ),
278 ],
279};
280
281pub mod kx_group {
286 pub use super::kx::{SECP256R1, SECP384R1, X25519};
287 pub use super::pq::{MLKEM768, SECP256R1MLKEM768, X25519MLKEM768};
288}
289
290pub static DEFAULT_KX_GROUPS: &[&dyn SupportedKxGroup] = &[
295 kx_group::X25519MLKEM768,
296 #[cfg(not(feature = "fips"))]
297 kx_group::X25519,
298 kx_group::SECP256R1,
299 kx_group::SECP384R1,
300];
301
302pub static ALL_KX_GROUPS: &[&dyn SupportedKxGroup] = &[
304 kx_group::X25519MLKEM768,
305 kx_group::SECP256R1MLKEM768,
306 kx_group::X25519,
307 kx_group::SECP256R1,
308 kx_group::SECP384R1,
309 kx_group::MLKEM768,
310];
311
312mod ring_shim {
314 use aws_lc_rs::agreement::{self, EphemeralPrivateKey, UnparsedPublicKey};
315
316 use crate::crypto::kx::SharedSecret;
317
318 pub(super) fn agree_ephemeral(
319 priv_key: EphemeralPrivateKey,
320 peer_key: &UnparsedPublicKey<&[u8]>,
321 ) -> Result<SharedSecret, ()> {
322 agreement::agree_ephemeral(priv_key, peer_key, (), |secret| {
323 Ok(SharedSecret::from(secret))
324 })
325 }
326}
327
328pub(super) fn fips() -> bool {
330 aws_lc_rs::try_fips_mode().is_ok()
331}
332
333pub(super) fn unspecified_err(e: aws_lc_rs::error::Unspecified) -> Error {
334 Error::Other(OtherError::new(e))
335}
336
337#[cfg(test)]
338mod tests {
339 #[cfg(feature = "fips")]
340 #[test]
341 fn default_suites_are_fips() {
342 assert!(
343 super::DEFAULT_TLS12_CIPHER_SUITES
344 .iter()
345 .all(|scs| scs.fips())
346 );
347 assert!(
348 super::DEFAULT_TLS13_CIPHER_SUITES
349 .iter()
350 .all(|scs| scs.fips())
351 );
352 }
353
354 #[cfg(not(feature = "fips"))]
355 #[test]
356 fn default_suites() {
357 assert_eq!(
358 super::DEFAULT_TLS12_CIPHER_SUITES,
359 super::ALL_TLS12_CIPHER_SUITES
360 );
361 assert_eq!(
362 super::DEFAULT_TLS13_CIPHER_SUITES,
363 super::ALL_TLS13_CIPHER_SUITES
364 );
365 }
366}