Coverage Report

Created: 2025-02-25 06:39

/rust/registry/src/index.crates.io-6f17d22bba15001f/rustls-0.23.22/src/tls13/mod.rs
Line
Count
Source (jump to first uncovered line)
1
use core::fmt;
2
3
use crate::crypto;
4
use crate::crypto::hash;
5
use crate::suites::{CipherSuiteCommon, SupportedCipherSuite};
6
7
pub(crate) mod key_schedule;
8
9
/// A TLS 1.3 cipher suite supported by rustls.
10
pub struct Tls13CipherSuite {
11
    /// Common cipher suite fields.
12
    pub common: CipherSuiteCommon,
13
14
    /// How to complete HKDF with the suite's hash function.
15
    ///
16
    /// If you have a HKDF implementation, you should directly implement the `crypto::tls13::Hkdf`
17
    /// trait (and associated).
18
    ///
19
    /// If not, you can implement the [`crypto::hmac::Hmac`] trait (and associated), and then use
20
    /// [`crypto::tls13::HkdfUsingHmac`].
21
    pub hkdf_provider: &'static dyn crypto::tls13::Hkdf,
22
23
    /// How to produce a [MessageDecrypter] or [MessageEncrypter]
24
    /// from raw key material.
25
    ///
26
    /// [MessageDecrypter]: crate::crypto::cipher::MessageDecrypter
27
    /// [MessageEncrypter]: crate::crypto::cipher::MessageEncrypter
28
    pub aead_alg: &'static dyn crypto::cipher::Tls13AeadAlgorithm,
29
30
    /// How to create QUIC header and record protection algorithms
31
    /// for this suite.
32
    ///
33
    /// Provide `None` to opt out of QUIC support for this suite.  It will
34
    /// not be offered in QUIC handshakes.
35
    pub quic: Option<&'static dyn crate::quic::Algorithm>,
36
}
37
38
impl Tls13CipherSuite {
39
    /// Can a session using suite self resume from suite prev?
40
0
    pub fn can_resume_from(&self, prev: &'static Self) -> Option<&'static Self> {
41
0
        (prev.common.hash_provider.algorithm() == self.common.hash_provider.algorithm())
42
0
            .then_some(prev)
43
0
    }
44
45
    /// Return `true` if this is backed by a FIPS-approved implementation.
46
    ///
47
    /// This means all the constituent parts that do cryptography return `true` for `fips()`.
48
0
    pub fn fips(&self) -> bool {
49
0
        let Self {
50
0
            common,
51
0
            hkdf_provider,
52
0
            aead_alg,
53
0
            quic,
54
0
        } = self;
55
0
        common.fips()
56
0
            && hkdf_provider.fips()
57
0
            && aead_alg.fips()
58
0
            && quic.map(|q| q.fips()).unwrap_or(true)
59
0
    }
60
61
    /// Returns a `quic::Suite` for the ciphersuite, if supported.
62
0
    pub fn quic_suite(&'static self) -> Option<crate::quic::Suite> {
63
0
        self.quic
64
0
            .map(|quic| crate::quic::Suite { quic, suite: self })
65
0
    }
66
}
67
68
impl From<&'static Tls13CipherSuite> for SupportedCipherSuite {
69
0
    fn from(s: &'static Tls13CipherSuite) -> Self {
70
0
        Self::Tls13(s)
71
0
    }
72
}
73
74
impl PartialEq for Tls13CipherSuite {
75
0
    fn eq(&self, other: &Self) -> bool {
76
0
        self.common.suite == other.common.suite
77
0
    }
78
}
79
80
impl fmt::Debug for Tls13CipherSuite {
81
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82
0
        f.debug_struct("Tls13CipherSuite")
83
0
            .field("suite", &self.common.suite)
84
0
            .finish()
85
0
    }
86
}
87
88
/// Constructs the signature message specified in section 4.4.3 of RFC8446.
89
0
pub(crate) fn construct_client_verify_message(handshake_hash: &hash::Output) -> VerifyMessage {
90
0
    VerifyMessage::new(handshake_hash, CLIENT_CONSTANT)
91
0
}
92
93
/// Constructs the signature message specified in section 4.4.3 of RFC8446.
94
0
pub(crate) fn construct_server_verify_message(handshake_hash: &hash::Output) -> VerifyMessage {
95
0
    VerifyMessage::new(handshake_hash, SERVER_CONSTANT)
96
0
}
97
98
pub(crate) struct VerifyMessage {
99
    buf: [u8; MAX_VERIFY_MSG],
100
    used: usize,
101
}
102
103
impl VerifyMessage {
104
0
    fn new(handshake_hash: &hash::Output, context_string_with_0: &[u8; 34]) -> Self {
105
0
        let used = 64 + context_string_with_0.len() + handshake_hash.as_ref().len();
106
0
        let mut buf = [0x20u8; MAX_VERIFY_MSG];
107
0
108
0
        let (_spaces, context) = buf.split_at_mut(64);
109
0
        let (context, hash) = context.split_at_mut(34);
110
0
        context.copy_from_slice(context_string_with_0);
111
0
        hash[..handshake_hash.as_ref().len()].copy_from_slice(handshake_hash.as_ref());
112
0
113
0
        Self { buf, used }
114
0
    }
115
}
116
117
impl AsRef<[u8]> for VerifyMessage {
118
0
    fn as_ref(&self) -> &[u8] {
119
0
        &self.buf[..self.used]
120
0
    }
121
}
122
123
const SERVER_CONSTANT: &[u8; 34] = b"TLS 1.3, server CertificateVerify\x00";
124
const CLIENT_CONSTANT: &[u8; 34] = b"TLS 1.3, client CertificateVerify\x00";
125
const MAX_VERIFY_MSG: usize = 64 + CLIENT_CONSTANT.len() + hash::Output::MAX_LEN;