Skip to main content

mls_spec/drafts/
targeted_messages.rs

1use crate::{
2    SensitiveBytes,
3    defs::{Epoch, LeafIndex, ProtocolVersion, WireFormat, labels::KdfLabelKind},
4    group::{GroupId, GroupIdRef},
5};
6
7pub const WIRE_FORMAT_MLS_TARGETED_MESSAGE: u16 = 0x0006;
8
9#[derive(
10    Debug,
11    Clone,
12    PartialEq,
13    Eq,
14    tls_codec::TlsSerialize,
15    tls_codec::TlsDeserialize,
16    tls_codec::TlsSize,
17)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19pub struct TargetedMessageSenderAuthData {
20    pub sender_leaf_index: LeafIndex,
21    pub signature: SensitiveBytes,
22    pub kem_output: SensitiveBytes,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq, tls_codec::TlsSerialize, tls_codec::TlsSize)]
26pub struct TargetedMessageTBM<'a> {
27    #[tls_codec(with = "crate::tlspl::bytes")]
28    pub group_id: GroupIdRef<'a>,
29    pub epoch: &'a Epoch,
30    pub recipient_leaf_index: &'a LeafIndex,
31    #[tls_codec(with = "crate::tlspl::bytes")]
32    pub authenticated_data: &'a [u8],
33    pub sender_auth_data: &'a TargetedMessageSenderAuthData,
34}
35
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub struct TargetedMessageTBS<'a> {
38    pub group_id: GroupIdRef<'a>,
39    pub epoch: &'a Epoch,
40    pub recipient_leaf_index: &'a LeafIndex,
41    pub authenticated_data: &'a [u8],
42    pub sender_leaf_index: &'a LeafIndex,
43    pub kem_output: &'a [u8],
44    pub ciphertext: &'a [u8],
45}
46
47impl<'a> tls_codec::Size for TargetedMessageTBS<'a> {
48    fn tls_serialized_len(&self) -> usize {
49        ProtocolVersion::Mls10.tls_serialized_len()
50            + WireFormat::new_unchecked(WireFormat::MLS_TARGETED_MESSAGE).tls_serialized_len()
51            + crate::tlspl::bytes::tls_serialized_len(self.group_id)
52            + self.epoch.tls_serialized_len()
53            + self.recipient_leaf_index.tls_serialized_len()
54            + crate::tlspl::bytes::tls_serialized_len(self.authenticated_data)
55            + self.sender_leaf_index.tls_serialized_len()
56            + crate::tlspl::bytes::tls_serialized_len(self.kem_output)
57            + crate::tlspl::bytes::tls_serialized_len(self.ciphertext)
58    }
59}
60
61impl<'a> tls_codec::Serialize for TargetedMessageTBS<'a> {
62    fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, tls_codec::Error> {
63        let mut written = ProtocolVersion::Mls10.tls_serialize(writer)?;
64        written +=
65            WireFormat::new_unchecked(WireFormat::MLS_TARGETED_MESSAGE).tls_serialize(writer)?;
66        written += crate::tlspl::bytes::tls_serialize(self.group_id, writer)?;
67        written += self.epoch.tls_serialize(writer)?;
68        written += self.recipient_leaf_index.tls_serialize(writer)?;
69        written += crate::tlspl::bytes::tls_serialize(self.authenticated_data, writer)?;
70        written += self.sender_leaf_index.tls_serialize(writer)?;
71        written += crate::tlspl::bytes::tls_serialize(self.kem_output, writer)?;
72        written += crate::tlspl::bytes::tls_serialize(self.ciphertext, writer)?;
73
74        Ok(written)
75    }
76}
77
78#[derive(
79    Debug,
80    Clone,
81    PartialEq,
82    Eq,
83    tls_codec::TlsSerialize,
84    tls_codec::TlsDeserialize,
85    tls_codec::TlsSize,
86)]
87#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
88pub struct TargetedMessage {
89    pub group_id: GroupId,
90    pub epoch: Epoch,
91    pub recipient_leaf_index: LeafIndex,
92    pub authenticated_data: SensitiveBytes,
93    pub encrypted_sender_auth_data: SensitiveBytes,
94    pub ciphertext: SensitiveBytes,
95}
96
97#[derive(Debug, Clone, PartialEq, Eq, tls_codec::TlsSerialize, tls_codec::TlsSize)]
98pub struct TargetedMessagePreSharedKeyId<'a> {
99    #[tls_codec(with = "crate::tlspl::bytes")]
100    pub group_id: GroupIdRef<'a>,
101    pub epoch: &'a Epoch,
102}
103
104impl TargetedMessagePreSharedKeyId<'_> {
105    pub const LABEL: KdfLabelKind = KdfLabelKind::TargetedMessagePsk;
106}
107
108#[derive(Debug, Clone, PartialEq, Eq, tls_codec::TlsSerialize, tls_codec::TlsSize)]
109pub struct TargetedMessageSenderAuthDataAAD<'a> {
110    #[tls_codec(with = "crate::tlspl::bytes")]
111    pub group_id: GroupIdRef<'a>,
112    pub epoch: &'a Epoch,
113    pub recipient_leaf_index: &'a LeafIndex,
114}
115
116#[derive(Debug, Clone, PartialEq, Eq)]
117#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
118pub struct TargetedMessageContent {
119    pub application_data: Vec<u8>,
120    pub padding_len: usize,
121}
122
123impl tls_codec::Size for TargetedMessageContent {
124    fn tls_serialized_len(&self) -> usize {
125        crate::tlspl::tls_serialized_len_as_vlvec(self.application_data.len()) + self.padding_len
126    }
127}
128
129impl tls_codec::Serialize for TargetedMessageContent {
130    fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, tls_codec::Error> {
131        let mut written = crate::tlspl::bytes::tls_serialize(&self.application_data, writer)?;
132        writer.write_all(&vec![0u8; self.padding_len][..])?;
133        written += self.padding_len;
134        Ok(written)
135    }
136}
137
138impl tls_codec::Deserialize for TargetedMessageContent {
139    fn tls_deserialize<R: std::io::Read>(bytes: &mut R) -> Result<Self, tls_codec::Error>
140    where
141        Self: Sized,
142    {
143        let application_data = crate::tlspl::bytes::tls_deserialize(bytes)?;
144        let padding_len = crate::messages::PrivateMessageContent::consume_padding(bytes)?;
145        Ok(Self {
146            application_data,
147            padding_len,
148        })
149    }
150}