1 use crate::cipher::{MessageDecrypter, MessageEncrypter};
2 use crate::conn::CommonState;
3 use crate::conn::ConnectionRandoms;
4 use crate::kx;
5 use crate::msgs::codec::{Codec, Reader};
6 use crate::msgs::enums::{AlertDescription, ContentType};
7 use crate::msgs::enums::{CipherSuite, SignatureScheme};
8 use crate::msgs::handshake::KeyExchangeAlgorithm;
9 use crate::suites::{BulkAlgorithm, CipherSuiteCommon, SupportedCipherSuite};
10 use crate::Error;
11 
12 use ring::aead;
13 use ring::digest::Digest;
14 
15 use std::fmt;
16 
17 mod cipher;
18 pub(crate) use cipher::{AesGcm, ChaCha20Poly1305, Tls12AeadAlgorithm};
19 
20 mod prf;
21 
22 /// The TLS1.2 ciphersuite TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256.
23 #[cfg(feature = "tls12")]
24 pub static TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite =
25     SupportedCipherSuite::Tls12(&Tls12CipherSuite {
26         common: CipherSuiteCommon {
27             suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
28             bulk: BulkAlgorithm::Chacha20Poly1305,
29             aead_algorithm: &ring::aead::CHACHA20_POLY1305,
30         },
31         kx: KeyExchangeAlgorithm::ECDHE,
32         sign: TLS12_ECDSA_SCHEMES,
33         fixed_iv_len: 12,
34         explicit_nonce_len: 0,
35         aead_alg: &ChaCha20Poly1305,
36         hmac_algorithm: ring::hmac::HMAC_SHA256,
37     });
38 
39 /// The TLS1.2 ciphersuite TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
40 #[cfg(feature = "tls12")]
41 pub static TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite =
42     SupportedCipherSuite::Tls12(&Tls12CipherSuite {
43         common: CipherSuiteCommon {
44             suite: CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
45             bulk: BulkAlgorithm::Chacha20Poly1305,
46             aead_algorithm: &ring::aead::CHACHA20_POLY1305,
47         },
48         kx: KeyExchangeAlgorithm::ECDHE,
49         sign: TLS12_RSA_SCHEMES,
50         fixed_iv_len: 12,
51         explicit_nonce_len: 0,
52         aead_alg: &ChaCha20Poly1305,
53         hmac_algorithm: ring::hmac::HMAC_SHA256,
54     });
55 
56 /// The TLS1.2 ciphersuite TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
57 #[cfg(feature = "tls12")]
58 pub static TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite =
59     SupportedCipherSuite::Tls12(&Tls12CipherSuite {
60         common: CipherSuiteCommon {
61             suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
62             bulk: BulkAlgorithm::Aes128Gcm,
63             aead_algorithm: &ring::aead::AES_128_GCM,
64         },
65         kx: KeyExchangeAlgorithm::ECDHE,
66         sign: TLS12_RSA_SCHEMES,
67         fixed_iv_len: 4,
68         explicit_nonce_len: 8,
69         aead_alg: &AesGcm,
70         hmac_algorithm: ring::hmac::HMAC_SHA256,
71     });
72 
73 /// The TLS1.2 ciphersuite TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
74 #[cfg(feature = "tls12")]
75 pub static TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite =
76     SupportedCipherSuite::Tls12(&Tls12CipherSuite {
77         common: CipherSuiteCommon {
78             suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
79             bulk: BulkAlgorithm::Aes256Gcm,
80             aead_algorithm: &ring::aead::AES_256_GCM,
81         },
82         kx: KeyExchangeAlgorithm::ECDHE,
83         sign: TLS12_RSA_SCHEMES,
84         fixed_iv_len: 4,
85         explicit_nonce_len: 8,
86         aead_alg: &AesGcm,
87         hmac_algorithm: ring::hmac::HMAC_SHA384,
88     });
89 
90 /// The TLS1.2 ciphersuite TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
91 #[cfg(feature = "tls12")]
92 pub static TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite =
93     SupportedCipherSuite::Tls12(&Tls12CipherSuite {
94         common: CipherSuiteCommon {
95             suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
96             bulk: BulkAlgorithm::Aes128Gcm,
97             aead_algorithm: &ring::aead::AES_128_GCM,
98         },
99         kx: KeyExchangeAlgorithm::ECDHE,
100         sign: TLS12_ECDSA_SCHEMES,
101         fixed_iv_len: 4,
102         explicit_nonce_len: 8,
103         aead_alg: &AesGcm,
104         hmac_algorithm: ring::hmac::HMAC_SHA256,
105     });
106 
107 /// The TLS1.2 ciphersuite TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
108 #[cfg(feature = "tls12")]
109 pub static TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite =
110     SupportedCipherSuite::Tls12(&Tls12CipherSuite {
111         common: CipherSuiteCommon {
112             suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
113             bulk: BulkAlgorithm::Aes256Gcm,
114             aead_algorithm: &ring::aead::AES_256_GCM,
115         },
116         kx: KeyExchangeAlgorithm::ECDHE,
117         sign: TLS12_ECDSA_SCHEMES,
118         fixed_iv_len: 4,
119         explicit_nonce_len: 8,
120         aead_alg: &AesGcm,
121         hmac_algorithm: ring::hmac::HMAC_SHA384,
122     });
123 
124 #[cfg(feature = "tls12")]
125 static TLS12_ECDSA_SCHEMES: &[SignatureScheme] = &[
126     SignatureScheme::ED25519,
127     SignatureScheme::ECDSA_NISTP521_SHA512,
128     SignatureScheme::ECDSA_NISTP384_SHA384,
129     SignatureScheme::ECDSA_NISTP256_SHA256,
130 ];
131 
132 #[cfg(feature = "tls12")]
133 static TLS12_RSA_SCHEMES: &[SignatureScheme] = &[
134     SignatureScheme::RSA_PSS_SHA512,
135     SignatureScheme::RSA_PSS_SHA384,
136     SignatureScheme::RSA_PSS_SHA256,
137     SignatureScheme::RSA_PKCS1_SHA512,
138     SignatureScheme::RSA_PKCS1_SHA384,
139     SignatureScheme::RSA_PKCS1_SHA256,
140 ];
141 
142 /// A TLS 1.2 cipher suite supported by rustls.
143 #[cfg(feature = "tls12")]
144 pub struct Tls12CipherSuite {
145     /// Common cipher suite fields.
146     pub common: CipherSuiteCommon,
147     pub(crate) hmac_algorithm: ring::hmac::Algorithm,
148     /// How to exchange/agree keys.
149     pub kx: KeyExchangeAlgorithm,
150 
151     /// How to sign messages for authentication.
152     pub sign: &'static [SignatureScheme],
153 
154     /// How long the fixed part of the 'IV' is.
155     ///
156     /// This isn't usually an IV, but we continue the
157     /// terminology misuse to match the standard.
158     pub fixed_iv_len: usize,
159 
160     /// This is a non-standard extension which extends the
161     /// key block to provide an initial explicit nonce offset,
162     /// in a deterministic and safe way.  GCM needs this,
163     /// chacha20poly1305 works this way by design.
164     pub explicit_nonce_len: usize,
165 
166     pub(crate) aead_alg: &'static dyn Tls12AeadAlgorithm,
167 }
168 
169 #[cfg(feature = "tls12")]
170 impl Tls12CipherSuite {
171     /// Resolve the set of supported `SignatureScheme`s from the
172     /// offered `SupportedSignatureSchemes`.  If we return an empty
173     /// set, the handshake terminates.
resolve_sig_schemes(&self, offered: &[SignatureScheme]) -> Vec<SignatureScheme>174     pub fn resolve_sig_schemes(&self, offered: &[SignatureScheme]) -> Vec<SignatureScheme> {
175         self.sign
176             .iter()
177             .filter(|pref| offered.contains(pref))
178             .cloned()
179             .collect()
180     }
181 
182     /// Which hash function to use with this suite.
hash_algorithm(&self) -> &'static ring::digest::Algorithm183     pub fn hash_algorithm(&self) -> &'static ring::digest::Algorithm {
184         self.hmac_algorithm.digest_algorithm()
185     }
186 }
187 
188 #[cfg(feature = "tls12")]
189 impl From<&'static Tls12CipherSuite> for SupportedCipherSuite {
from(s: &'static Tls12CipherSuite) -> Self190     fn from(s: &'static Tls12CipherSuite) -> Self {
191         Self::Tls12(s)
192     }
193 }
194 
195 #[cfg(feature = "tls12")]
196 impl PartialEq for Tls12CipherSuite {
eq(&self, other: &Self) -> bool197     fn eq(&self, other: &Self) -> bool {
198         self.common.suite == other.common.suite
199     }
200 }
201 
202 #[cfg(feature = "tls12")]
203 impl fmt::Debug for Tls12CipherSuite {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result204     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
205         f.debug_struct("Tls12CipherSuite")
206             .field("suite", &self.common.suite)
207             .field("bulk", &self.common.bulk)
208             .finish()
209     }
210 }
211 
212 /// TLS1.2 per-connection keying material
213 pub(crate) struct ConnectionSecrets {
214     pub(crate) randoms: ConnectionRandoms,
215     suite: &'static Tls12CipherSuite,
216     pub(crate) master_secret: [u8; 48],
217 }
218 
219 impl ConnectionSecrets {
new( randoms: &ConnectionRandoms, suite: &'static Tls12CipherSuite, pms: &[u8], ) -> Self220     pub(crate) fn new(
221         randoms: &ConnectionRandoms,
222         suite: &'static Tls12CipherSuite,
223         pms: &[u8],
224     ) -> Self {
225         let mut ret = Self {
226             randoms: randoms.clone(),
227             suite,
228             master_secret: [0u8; 48],
229         };
230 
231         let randoms = join_randoms(&ret.randoms.client, &ret.randoms.server);
232         prf::prf(
233             &mut ret.master_secret,
234             suite.hmac_algorithm,
235             pms,
236             b"master secret",
237             &randoms,
238         );
239         ret
240     }
241 
new_ems( randoms: &ConnectionRandoms, hs_hash: &Digest, suite: &'static Tls12CipherSuite, pms: &[u8], ) -> Self242     pub(crate) fn new_ems(
243         randoms: &ConnectionRandoms,
244         hs_hash: &Digest,
245         suite: &'static Tls12CipherSuite,
246         pms: &[u8],
247     ) -> Self {
248         let mut ret = Self {
249             randoms: randoms.clone(),
250             master_secret: [0u8; 48],
251             suite,
252         };
253 
254         prf::prf(
255             &mut ret.master_secret,
256             suite.hmac_algorithm,
257             pms,
258             b"extended master secret",
259             hs_hash.as_ref(),
260         );
261         ret
262     }
263 
new_resume( randoms: &ConnectionRandoms, suite: &'static Tls12CipherSuite, master_secret: &[u8], ) -> Self264     pub(crate) fn new_resume(
265         randoms: &ConnectionRandoms,
266         suite: &'static Tls12CipherSuite,
267         master_secret: &[u8],
268     ) -> Self {
269         let mut ret = Self {
270             randoms: randoms.clone(),
271             suite,
272             master_secret: [0u8; 48],
273         };
274         ret.master_secret
275             .copy_from_slice(master_secret);
276         ret
277     }
278 
279     /// Make a `MessageCipherPair` based on the given supported ciphersuite `scs`,
280     /// and the session's `secrets`.
make_cipher_pair(&self) -> MessageCipherPair281     pub(crate) fn make_cipher_pair(&self) -> MessageCipherPair {
282         fn split_key<'a>(
283             key_block: &'a [u8],
284             alg: &'static aead::Algorithm,
285         ) -> (aead::LessSafeKey, &'a [u8]) {
286             // Might panic if the key block is too small.
287             let (key, rest) = key_block.split_at(alg.key_len());
288             // Won't panic because its only prerequisite is that `key` is `alg.key_len()` bytes long.
289             let key = aead::UnboundKey::new(alg, key).unwrap();
290             (aead::LessSafeKey::new(key), rest)
291         }
292 
293         // Make a key block, and chop it up.
294         // nb. we don't implement any ciphersuites with nonzero mac_key_len.
295         let key_block = self.make_key_block();
296 
297         let suite = self.suite;
298         let scs = &suite.common;
299 
300         let (client_write_key, key_block) = split_key(&key_block, scs.aead_algorithm);
301         let (server_write_key, key_block) = split_key(key_block, scs.aead_algorithm);
302         let (client_write_iv, key_block) = key_block.split_at(suite.fixed_iv_len);
303         let (server_write_iv, extra) = key_block.split_at(suite.fixed_iv_len);
304 
305         let (write_key, write_iv, read_key, read_iv) = if self.randoms.we_are_client {
306             (
307                 client_write_key,
308                 client_write_iv,
309                 server_write_key,
310                 server_write_iv,
311             )
312         } else {
313             (
314                 server_write_key,
315                 server_write_iv,
316                 client_write_key,
317                 client_write_iv,
318             )
319         };
320 
321         (
322             suite
323                 .aead_alg
324                 .decrypter(read_key, read_iv),
325             suite
326                 .aead_alg
327                 .encrypter(write_key, write_iv, extra),
328         )
329     }
330 
make_key_block(&self) -> Vec<u8>331     fn make_key_block(&self) -> Vec<u8> {
332         let suite = &self.suite;
333         let common = &self.suite.common;
334 
335         let len =
336             (common.aead_algorithm.key_len() + suite.fixed_iv_len) * 2 + suite.explicit_nonce_len;
337 
338         let mut out = Vec::new();
339         out.resize(len, 0u8);
340 
341         // NOTE: opposite order to above for no good reason.
342         // Don't design security protocols on drugs, kids.
343         let randoms = join_randoms(&self.randoms.server, &self.randoms.client);
344         prf::prf(
345             &mut out,
346             self.suite.hmac_algorithm,
347             &self.master_secret,
348             b"key expansion",
349             &randoms,
350         );
351 
352         out
353     }
354 
suite(&self) -> &'static Tls12CipherSuite355     pub(crate) fn suite(&self) -> &'static Tls12CipherSuite {
356         self.suite
357     }
358 
get_master_secret(&self) -> Vec<u8>359     pub(crate) fn get_master_secret(&self) -> Vec<u8> {
360         let mut ret = Vec::new();
361         ret.extend_from_slice(&self.master_secret);
362         ret
363     }
364 
make_verify_data(&self, handshake_hash: &Digest, label: &[u8]) -> Vec<u8>365     fn make_verify_data(&self, handshake_hash: &Digest, label: &[u8]) -> Vec<u8> {
366         let mut out = Vec::new();
367         out.resize(12, 0u8);
368 
369         prf::prf(
370             &mut out,
371             self.suite.hmac_algorithm,
372             &self.master_secret,
373             label,
374             handshake_hash.as_ref(),
375         );
376         out
377     }
378 
client_verify_data(&self, handshake_hash: &Digest) -> Vec<u8>379     pub(crate) fn client_verify_data(&self, handshake_hash: &Digest) -> Vec<u8> {
380         self.make_verify_data(handshake_hash, b"client finished")
381     }
382 
server_verify_data(&self, handshake_hash: &Digest) -> Vec<u8>383     pub(crate) fn server_verify_data(&self, handshake_hash: &Digest) -> Vec<u8> {
384         self.make_verify_data(handshake_hash, b"server finished")
385     }
386 
export_keying_material( &self, output: &mut [u8], label: &[u8], context: Option<&[u8]>, )387     pub(crate) fn export_keying_material(
388         &self,
389         output: &mut [u8],
390         label: &[u8],
391         context: Option<&[u8]>,
392     ) {
393         let mut randoms = Vec::new();
394         randoms.extend_from_slice(&self.randoms.client);
395         randoms.extend_from_slice(&self.randoms.server);
396         if let Some(context) = context {
397             assert!(context.len() <= 0xffff);
398             (context.len() as u16).encode(&mut randoms);
399             randoms.extend_from_slice(context);
400         }
401 
402         prf::prf(
403             output,
404             self.suite.hmac_algorithm,
405             &self.master_secret,
406             label,
407             &randoms,
408         )
409     }
410 }
411 
join_randoms(first: &[u8; 32], second: &[u8; 32]) -> [u8; 64]412 fn join_randoms(first: &[u8; 32], second: &[u8; 32]) -> [u8; 64] {
413     let mut randoms = [0u8; 64];
414     randoms[..32].copy_from_slice(first);
415     randoms[32..].copy_from_slice(second);
416     randoms
417 }
418 
419 type MessageCipherPair = (Box<dyn MessageDecrypter>, Box<dyn MessageEncrypter>);
420 
decode_ecdh_params<T: Codec>( common: &mut CommonState, kx_params: &[u8], ) -> Result<T, Error>421 pub(crate) fn decode_ecdh_params<T: Codec>(
422     common: &mut CommonState,
423     kx_params: &[u8],
424 ) -> Result<T, Error> {
425     decode_ecdh_params_::<T>(kx_params).ok_or_else(|| {
426         common.send_fatal_alert(AlertDescription::DecodeError);
427         Error::CorruptMessagePayload(ContentType::Handshake)
428     })
429 }
430 
decode_ecdh_params_<T: Codec>(kx_params: &[u8]) -> Option<T>431 fn decode_ecdh_params_<T: Codec>(kx_params: &[u8]) -> Option<T> {
432     let mut rd = Reader::init(kx_params);
433     let ecdh_params = T::read(&mut rd)?;
434     match rd.any_left() {
435         false => Some(ecdh_params),
436         true => None,
437     }
438 }
439 
complete_ecdh( mine: kx::KeyExchange, peer_pub_key: &[u8], ) -> Result<kx::KeyExchangeResult, Error>440 pub(crate) fn complete_ecdh(
441     mine: kx::KeyExchange,
442     peer_pub_key: &[u8],
443 ) -> Result<kx::KeyExchangeResult, Error> {
444     mine.complete(peer_pub_key)
445         .ok_or_else(|| Error::PeerMisbehavedError("key agreement failed".to_string()))
446 }
447 
448 #[cfg(test)]
449 mod tests {
450     use super::*;
451     use crate::msgs::handshake::{ClientECDHParams, ServerECDHParams};
452 
453     #[test]
server_ecdhe_remaining_bytes()454     fn server_ecdhe_remaining_bytes() {
455         let key = kx::KeyExchange::start(&kx::X25519).unwrap();
456         let server_params = ServerECDHParams::new(key.group(), key.pubkey.as_ref());
457         let mut server_buf = Vec::new();
458         server_params.encode(&mut server_buf);
459         server_buf.push(34);
460         assert!(decode_ecdh_params_::<ServerECDHParams>(&server_buf).is_none());
461     }
462 
463     #[test]
client_ecdhe_invalid()464     fn client_ecdhe_invalid() {
465         assert!(decode_ecdh_params_::<ClientECDHParams>(&[34]).is_none());
466     }
467 }
468