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;
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
21pub mod hpke;
23pub(crate) mod pq;
25pub 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
42pub 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
98pub static DEFAULT_CIPHER_SUITES: &[SupportedCipherSuite] = &[
103 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 #[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
123pub static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = &[
125 tls13::TLS13_AES_256_GCM_SHA384,
127 tls13::TLS13_AES_128_GCM_SHA256,
128 tls13::TLS13_CHACHA20_POLY1305_SHA256,
129 #[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
144pub 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
157static 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 (
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
241pub mod kx_group {
246 pub use super::kx::{SECP256R1, SECP384R1, X25519};
247 pub use super::pq::{MLKEM768, MLKEM1024, SECP256R1MLKEM768, X25519MLKEM768};
248}
249
250pub 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
264pub 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
284mod 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
299pub(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 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}