1use alloc::vec::Vec;
2
3pub(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
20pub mod hpke;
22pub(crate) mod pq;
24pub 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
41pub 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
97pub static DEFAULT_CIPHER_SUITES: &[SupportedCipherSuite] = &[
102 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 #[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
122pub static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = &[
124 tls13::TLS13_AES_256_GCM_SHA384,
126 tls13::TLS13_AES_128_GCM_SHA256,
127 tls13::TLS13_CHACHA20_POLY1305_SHA256,
128 #[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
143pub 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
156static 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 (
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
240pub mod kx_group {
245 pub use super::kx::{SECP256R1, SECP384R1, X25519};
246 pub use super::pq::{MLKEM768, MLKEM1024, SECP256R1MLKEM768, X25519MLKEM768};
247}
248
249pub 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
263pub 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
283mod 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
298pub(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 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}