clia_rustls_mod/tls13/
mod.rs

1use alloc::vec::Vec;
2use core::fmt;
3
4use crate::crypto;
5use crate::crypto::hash;
6use crate::suites::{CipherSuiteCommon, SupportedCipherSuite};
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    /// Return `true` if this is backed by a FIPS-approved implementation.
47    ///
48    /// This means all the constituent parts that do cryptography return `true` for `fips()`.
49    pub fn fips(&self) -> bool {
50        let Self {
51            common,
52            hkdf_provider,
53            aead_alg,
54            quic,
55        } = self;
56        common.fips()
57            && hkdf_provider.fips()
58            && aead_alg.fips()
59            && quic.map(|q| q.fips()).unwrap_or(true)
60    }
61
62    /// Returns a `quic::Suite` for the ciphersuite, if supported.
63    pub fn quic_suite(&'static self) -> Option<crate::quic::Suite> {
64        self.quic
65            .map(|quic| crate::quic::Suite { quic, suite: self })
66    }
67}
68
69impl From<&'static Tls13CipherSuite> for SupportedCipherSuite {
70    fn from(s: &'static Tls13CipherSuite) -> Self {
71        Self::Tls13(s)
72    }
73}
74
75impl PartialEq for Tls13CipherSuite {
76    fn eq(&self, other: &Self) -> bool {
77        self.common.suite == other.common.suite
78    }
79}
80
81impl fmt::Debug for Tls13CipherSuite {
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        f.debug_struct("Tls13CipherSuite")
84            .field("suite", &self.common.suite)
85            .finish()
86    }
87}
88
89/// Constructs the signature message specified in section 4.4.3 of RFC8446.
90pub(crate) fn construct_client_verify_message(handshake_hash: &hash::Output) -> Vec<u8> {
91    construct_verify_message(handshake_hash, b"TLS 1.3, client CertificateVerify\x00")
92}
93
94/// Constructs the signature message specified in section 4.4.3 of RFC8446.
95pub(crate) fn construct_server_verify_message(handshake_hash: &hash::Output) -> Vec<u8> {
96    construct_verify_message(handshake_hash, b"TLS 1.3, server CertificateVerify\x00")
97}
98
99fn construct_verify_message(
100    handshake_hash: &hash::Output,
101    context_string_with_0: &[u8],
102) -> Vec<u8> {
103    let mut msg = Vec::new();
104    msg.resize(64, 0x20u8);
105    msg.extend_from_slice(context_string_with_0);
106    msg.extend_from_slice(handshake_hash.as_ref());
107    msg
108}