mls_spec/messages/
content_encryption.rs

1use crate::{
2    defs::{Epoch, Generation, LeafIndex},
3    messages::{ContentType, ContentTypeInner, FramedContentAuthData},
4};
5
6pub type ReuseGuard = [u8; 4];
7
8#[derive(Debug, Clone)]
9pub struct PrivateMessageContent {
10    pub inner: ContentTypeInner,
11    pub auth: FramedContentAuthData,
12    pub padding_len: usize,
13}
14
15impl PartialEq for PrivateMessageContent {
16    fn eq(&self, other: &Self) -> bool {
17        self.inner == other.inner && self.auth == other.auth
18    }
19}
20impl Eq for PrivateMessageContent {}
21
22impl tls_codec::Size for PrivateMessageContent {
23    fn tls_serialized_len(&self) -> usize {
24        self.inner.tls_serialized_len() + self.auth.tls_serialized_len() + self.padding_len
25    }
26}
27
28impl tls_codec::Serialize for PrivateMessageContent {
29    fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, tls_codec::Error> {
30        let mut written = 0;
31        written += self.inner.tls_serialize(writer)?;
32        written += self.auth.tls_serialize(writer)?;
33        writer.write_all(&vec![0u8; self.padding_len][..])?;
34        written += self.padding_len;
35        Ok(written)
36    }
37}
38
39impl PrivateMessageContent {
40    pub(crate) fn consume_padding<R: std::io::Read>(
41        bytes: &mut R,
42    ) -> Result<usize, tls_codec::Error> {
43        let mut padding = Vec::new();
44        bytes.read_to_end(&mut padding).map_err(|_| {
45            tls_codec::Error::DecodingError("Cannot decode padding past MessageContent".into())
46        })?;
47
48        let padding_len = padding.len();
49        if padding.into_iter().any(|b| b != 0x00) {
50            return Err(tls_codec::Error::DecodingError(
51                "MessageContent padding isn't all zeroes!".into(),
52            ));
53        }
54
55        Ok(padding_len)
56    }
57
58    pub fn tls_deserialize_with_content_type<R: std::io::Read>(
59        bytes: &mut R,
60        content_type: ContentType,
61    ) -> Result<Self, tls_codec::Error> {
62        use tls_codec::Deserialize as _;
63
64        let inner = match content_type {
65            ContentType::Reserved => {
66                return Err(tls_codec::Error::DecodingError(
67                    "Tried to deserialize a ContentType::RESERVED, which is invalid".into(),
68                ));
69            }
70            ContentType::Application => ContentTypeInner::Application {
71                application_data: crate::tlspl::bytes::tls_deserialize(bytes)?,
72            },
73            ContentType::Proposal => ContentTypeInner::Proposal {
74                proposal: <_>::tls_deserialize(bytes)?,
75            },
76            ContentType::Commit => ContentTypeInner::Commit {
77                commit: <_>::tls_deserialize(bytes)?,
78            },
79            #[cfg(feature = "draft-mularczyk-mls-splitcommit")]
80            ContentType::SplitCommit => ContentTypeInner::SplitCommit {
81                split_commit: <_>::tls_deserialize(bytes)?,
82            },
83        };
84        let auth = FramedContentAuthData::tls_deserialize_with_content_type(bytes, content_type)?;
85
86        let padding_len = Self::consume_padding(bytes)?;
87
88        Ok(Self {
89            inner,
90            auth,
91            padding_len,
92        })
93    }
94}
95
96/// PrivateMessage content AAD struct
97///
98/// <https://www.rfc-editor.org/rfc/rfc9420.html#section-6.3.1-9>
99///
100/// # TLS Presentation Language
101///
102/// ```notrust,ignore
103/// struct {
104///     opaque group_id<V>;
105///     uint64 epoch;
106///     ContentType content_type;
107///     opaque authenticated_data<V>;
108/// } PrivateContentAAD;
109/// ````
110#[derive(Debug, Clone, PartialEq, Eq, tls_codec::TlsSerialize, tls_codec::TlsSize)]
111pub struct PrivateContentAAD<'a> {
112    #[tls_codec(with = "crate::tlspl::bytes")]
113    pub group_id: &'a [u8],
114    pub epoch: &'a Epoch,
115    pub content_type: &'a ContentType,
116    #[tls_codec(with = "crate::tlspl::bytes")]
117    pub authenticated_data: &'a [u8],
118}
119
120/// SenderData struct
121///
122/// <https://www.rfc-editor.org/rfc/rfc9420.html#name-sender-data-encryption>
123///
124/// # TLS Presentation Language
125///
126/// ```notrust,ignore
127/// struct {
128///     uint32 leaf_index;
129///     uint32 generation;
130///     opaque reuse_guard[4];
131/// } SenderData;
132/// ```
133#[derive(
134    Debug,
135    Clone,
136    PartialEq,
137    Eq,
138    tls_codec::TlsSerialize,
139    tls_codec::TlsDeserialize,
140    tls_codec::TlsSize,
141)]
142pub struct SenderData {
143    pub leaf_index: LeafIndex,
144    pub generation: Generation,
145    pub reuse_guard: ReuseGuard,
146}
147
148/// SenderData AAD struct
149///
150/// <https://www.rfc-editor.org/rfc/rfc9420.html#section-6.3.2-7>
151///
152/// # TLS Presentation Language
153///
154/// ```notrust,ignore
155/// struct {
156///     opaque group_id<V>;
157///     uint64 epoch;
158///     ContentType content_type;
159/// } SenderDataAAD;
160/// ````
161#[derive(Debug, Clone, PartialEq, Eq, tls_codec::TlsSerialize, tls_codec::TlsSize)]
162pub struct SenderDataAAD<'a> {
163    pub group_id: &'a [u8],
164    pub epoch: &'a Epoch,
165    pub content_type: &'a ContentType,
166}