1use crate::crypto;
2use crate::crypto::hash;
3use crate::suites::{CipherSuiteCommon, SupportedCipherSuite};
4
5use alloc::vec::Vec;
6use core::fmt;
7
8pub(crate) mod key_schedule;
9
10/// A TLS 1.3 cipher suite supported by rustls.
11pub struct Tls13CipherSuite {
12 /// Common cipher suite fields.
13 pub common: CipherSuiteCommon,
14
15 /// How to complete HKDF with the suite's hash function.
16 ///
17 /// If you have a HKDF implementation, you should directly implement the `crypto::tls13::Hkdf`
18 /// trait (and associated).
19 ///
20 /// If not, you can implement the [`crypto::hmac::Hmac`] trait (and associated), and then use
21 /// [`crypto::tls13::HkdfUsingHmac`].
22 pub hkdf_provider: &'static dyn crypto::tls13::Hkdf,
23
24 /// How to produce a [MessageDecrypter] or [MessageEncrypter]
25 /// from raw key material.
26 ///
27 /// [MessageDecrypter]: crate::crypto::cipher::MessageDecrypter
28 /// [MessageEncrypter]: crate::crypto::cipher::MessageEncrypter
29 pub aead_alg: &'static dyn crypto::cipher::Tls13AeadAlgorithm,
30
31 /// How to create QUIC header and record protection algorithms
32 /// for this suite.
33 ///
34 /// Provide `None` to opt out of QUIC support for this suite. It will
35 /// not be offered in QUIC handshakes.
36 pub quic: Option<&'static dyn crate::quic::Algorithm>,
37}
38
39impl Tls13CipherSuite {
40 /// Can a session using suite self resume from suite prev?
41 pub fn can_resume_from(&self, prev: &'static Self) -> Option<&'static Self> {
42 (prev.common.hash_provider.algorithm() == self.common.hash_provider.algorithm())
43 .then(|| prev)
44 }
45}
46
47impl From<&'static Tls13CipherSuite> for SupportedCipherSuite {
48 fn from(s: &'static Tls13CipherSuite) -> Self {
49 Self::Tls13(s)
50 }
51}
52
53impl PartialEq for Tls13CipherSuite {
54 fn eq(&self, other: &Self) -> bool {
55 self.common.suite == other.common.suite
56 }
57}
58
59impl fmt::Debug for Tls13CipherSuite {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 f&mut DebugStruct<'_, '_>.debug_struct("Tls13CipherSuite")
62 .field(name:"suite", &self.common.suite)
63 .finish()
64 }
65}
66
67/// Constructs the signature message specified in section 4.4.3 of RFC8446.
68pub(crate) fn construct_client_verify_message(handshake_hash: &hash::Output) -> Vec<u8> {
69 construct_verify_message(handshake_hash, context_string_with_0:b"TLS 1.3, client CertificateVerify\x00")
70}
71
72/// Constructs the signature message specified in section 4.4.3 of RFC8446.
73pub(crate) fn construct_server_verify_message(handshake_hash: &hash::Output) -> Vec<u8> {
74 construct_verify_message(handshake_hash, context_string_with_0:b"TLS 1.3, server CertificateVerify\x00")
75}
76
77fn construct_verify_message(
78 handshake_hash: &hash::Output,
79 context_string_with_0: &[u8],
80) -> Vec<u8> {
81 let mut msg: Vec = Vec::new();
82 msg.resize(new_len:64, value:0x20u8);
83 msg.extend_from_slice(context_string_with_0);
84 msg.extend_from_slice(handshake_hash.as_ref());
85 msg
86}
87