1use rustls::crypto::tls12::PrfUsingHmac;
4use rustls::crypto::tls13::HkdfUsingHmac;
5use rustls::crypto::{CipherSuiteCommon, KeyExchangeAlgorithm};
6use rustls::{CipherSuite, SignatureScheme, SupportedCipherSuite};
7
8use crate::{aead, hash, hmac, quic};
9
10pub static ALL: &[SupportedCipherSuite] = &[
12 TLS13_AES_256_GCM_SHA384,
13 TLS13_AES_128_GCM_SHA256,
14 TLS13_CHACHA20_POLY1305_SHA256,
15 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
16 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
17 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
18 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
19 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
20 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
21];
22
23pub static TLS13_AES_256_GCM_SHA384: SupportedCipherSuite =
25 SupportedCipherSuite::Tls13(&rustls::Tls13CipherSuite {
26 common: CipherSuiteCommon {
27 suite: CipherSuite::TLS13_AES_256_GCM_SHA384,
28 hash_provider: &hash::SHA384,
29 confidentiality_limit: 1 << 24,
32 },
33 hkdf_provider: &HkdfUsingHmac(&hmac::SHA384),
34 aead_alg: &aead::TLS13_AES_256_GCM,
35 quic: Some(&quic::AES_256_GCM),
36 });
37
38pub static TLS13_AES_128_GCM_SHA256: SupportedCipherSuite =
40 SupportedCipherSuite::Tls13(&rustls::Tls13CipherSuite {
41 common: CipherSuiteCommon {
42 suite: CipherSuite::TLS13_AES_128_GCM_SHA256,
43 hash_provider: &hash::SHA256,
44 confidentiality_limit: 1 << 24,
45 },
46 hkdf_provider: &HkdfUsingHmac(&hmac::SHA256),
47 aead_alg: &aead::TLS13_AES_128_GCM,
48 quic: Some(&quic::AES_128_GCM),
49 });
50
51pub static TLS13_CHACHA20_POLY1305_SHA256: SupportedCipherSuite =
58 SupportedCipherSuite::Tls13(&rustls::Tls13CipherSuite {
59 common: CipherSuiteCommon {
60 suite: CipherSuite::TLS13_CHACHA20_POLY1305_SHA256,
61 hash_provider: &hash::SHA256,
62 confidentiality_limit: u64::MAX,
67 },
68 hkdf_provider: &HkdfUsingHmac(&hmac::SHA256),
69 aead_alg: &aead::TLS13_CHACHA20_POLY1305,
70 quic: Some(&quic::CHACHA20_POLY1305),
71 });
72
73pub static TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite =
78 SupportedCipherSuite::Tls12(&rustls::Tls12CipherSuite {
79 common: CipherSuiteCommon {
80 suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
81 hash_provider: &hash::SHA384,
82 confidentiality_limit: 1 << 23,
83 },
84 prf_provider: &PrfUsingHmac(&hmac::SHA384),
85 kx: KeyExchangeAlgorithm::ECDHE,
86 sign: TLS12_ECDSA_SCHEMES,
87 aead_alg: &aead::TLS12_AES_256_GCM,
88 });
89
90pub static TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite =
92 SupportedCipherSuite::Tls12(&rustls::Tls12CipherSuite {
93 common: CipherSuiteCommon {
94 suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
95 hash_provider: &hash::SHA256,
96 confidentiality_limit: 1 << 23,
97 },
98 prf_provider: &PrfUsingHmac(&hmac::SHA256),
99 kx: KeyExchangeAlgorithm::ECDHE,
100 sign: TLS12_ECDSA_SCHEMES,
101 aead_alg: &aead::TLS12_AES_128_GCM,
102 });
103
104pub static TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite =
109 SupportedCipherSuite::Tls12(&rustls::Tls12CipherSuite {
110 common: CipherSuiteCommon {
111 suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
112 hash_provider: &hash::SHA256,
113 confidentiality_limit: u64::MAX,
114 },
115 prf_provider: &PrfUsingHmac(&hmac::SHA256),
116 kx: KeyExchangeAlgorithm::ECDHE,
117 sign: TLS12_ECDSA_SCHEMES,
118 aead_alg: &aead::TLS12_CHACHA20_POLY1305,
119 });
120
121pub static TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite =
130 SupportedCipherSuite::Tls12(&rustls::Tls12CipherSuite {
131 common: CipherSuiteCommon {
132 suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
133 hash_provider: &hash::SHA384,
134 confidentiality_limit: 1 << 23,
135 },
136 prf_provider: &PrfUsingHmac(&hmac::SHA384),
137 kx: KeyExchangeAlgorithm::ECDHE,
138 sign: TLS12_RSA_SCHEMES,
139 aead_alg: &aead::TLS12_AES_256_GCM,
140 });
141
142pub static TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite =
144 SupportedCipherSuite::Tls12(&rustls::Tls12CipherSuite {
145 common: CipherSuiteCommon {
146 suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
147 hash_provider: &hash::SHA256,
148 confidentiality_limit: 1 << 23,
149 },
150 prf_provider: &PrfUsingHmac(&hmac::SHA256),
151 kx: KeyExchangeAlgorithm::ECDHE,
152 sign: TLS12_RSA_SCHEMES,
153 aead_alg: &aead::TLS12_AES_128_GCM,
154 });
155
156pub static TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite =
158 SupportedCipherSuite::Tls12(&rustls::Tls12CipherSuite {
159 common: CipherSuiteCommon {
160 suite: CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
161 hash_provider: &hash::SHA256,
162 confidentiality_limit: u64::MAX,
163 },
164 prf_provider: &PrfUsingHmac(&hmac::SHA256),
165 kx: KeyExchangeAlgorithm::ECDHE,
166 sign: TLS12_RSA_SCHEMES,
167 aead_alg: &aead::TLS12_CHACHA20_POLY1305,
168 });
169
170static TLS12_ECDSA_SCHEMES: &[SignatureScheme] = &[
180 SignatureScheme::ED25519,
181 SignatureScheme::ECDSA_NISTP384_SHA384,
182 SignatureScheme::ECDSA_NISTP256_SHA256,
183];
184
185static TLS12_RSA_SCHEMES: &[SignatureScheme] = &[
191 SignatureScheme::RSA_PSS_SHA512,
192 SignatureScheme::RSA_PSS_SHA384,
193 SignatureScheme::RSA_PSS_SHA256,
194 SignatureScheme::RSA_PKCS1_SHA512,
195 SignatureScheme::RSA_PKCS1_SHA384,
196 SignatureScheme::RSA_PKCS1_SHA256,
197];
198
199#[cfg(test)]
200mod tests {
201 use super::*;
202
203 #[test]
210 fn the_advertised_schemes_are_all_verifiable() {
211 let mapped: alloc::vec::Vec<SignatureScheme> = crate::SUPPORTED_SIG_ALGS
212 .mapping
213 .iter()
214 .map(|(scheme, _)| *scheme)
215 .collect();
216
217 let mut checked = 0;
218 for suite in ALL {
219 let SupportedCipherSuite::Tls12(t) = suite else {
220 continue;
221 };
222 for scheme in t.sign {
223 assert!(
224 mapped.contains(scheme),
225 "{:?} advertises {scheme:?}, which nothing here verifies",
226 suite.suite()
227 );
228 checked += 1;
229 }
230 }
231 assert!(checked >= 27, "only {checked} advertised schemes examined");
233 }
234
235 #[test]
238 fn each_suite_uses_the_hash_it_is_named_for() {
239 use rustls::crypto::hash::HashAlgorithm;
240
241 for (suite, want) in [
244 (&TLS13_AES_256_GCM_SHA384, HashAlgorithm::SHA384),
245 (&TLS13_AES_128_GCM_SHA256, HashAlgorithm::SHA256),
246 (
247 &TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
248 HashAlgorithm::SHA384,
249 ),
250 (
251 &TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
252 HashAlgorithm::SHA256,
253 ),
254 (&TLS13_CHACHA20_POLY1305_SHA256, HashAlgorithm::SHA256),
255 (
256 &TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
257 HashAlgorithm::SHA256,
258 ),
259 (
260 &TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
261 HashAlgorithm::SHA384,
262 ),
263 (
264 &TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
265 HashAlgorithm::SHA256,
266 ),
267 (
268 &TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
269 HashAlgorithm::SHA256,
270 ),
271 ] {
272 let got = match suite {
273 SupportedCipherSuite::Tls13(t) => t.common.hash_provider.algorithm(),
274 SupportedCipherSuite::Tls12(t) => t.common.hash_provider.algorithm(),
275 };
276 assert_eq!(got, want, "{:?} uses the wrong hash", suite.suite());
277 }
278 }
279
280 #[test]
283 fn the_suites_are_ordered_and_distinct() {
284 let names: alloc::vec::Vec<CipherSuite> = ALL.iter().map(|s| s.suite()).collect();
285 assert_eq!(names.len(), 9);
286 for (i, a) in names.iter().enumerate() {
287 assert!(!names[i + 1..].contains(a), "{a:?} is listed twice");
288 }
289 assert_eq!(names[0], CipherSuite::TLS13_AES_256_GCM_SHA384);
291 assert_eq!(names[1], CipherSuite::TLS13_AES_128_GCM_SHA256);
292 assert_eq!(names[2], CipherSuite::TLS13_CHACHA20_POLY1305_SHA256);
293 let first_12 = ALL
295 .iter()
296 .position(|s| matches!(s, SupportedCipherSuite::Tls12(_)))
297 .expect("there are TLS 1.2 suites");
298 assert!(
299 ALL[first_12..]
300 .iter()
301 .all(|s| matches!(s, SupportedCipherSuite::Tls12(_))),
302 "the TLS 1.3 and TLS 1.2 suites are interleaved"
303 );
304 }
305}