1use std::io::Cursor;
4
5use binrw::prelude::*;
6const SIGNATURE_SIZE: usize = 16;
7
8pub type EncryptionNonce = [u8; 16];
12
13#[binrw::binrw]
14#[derive(Debug, PartialEq, Eq)]
15#[brw(little, magic(b"\xfdSMB"))]
16pub struct EncryptedHeader {
17 pub signature: u128,
18 pub nonce: EncryptionNonce,
19 pub original_message_size: u32,
20 #[bw(calc = 0)]
21 #[br(assert(_reserved == 0))]
22 _reserved: u16,
23 #[bw(calc = 1)] #[br(assert(_flags == 1))]
25 _flags: u16,
26 pub session_id: u64,
27}
28
29impl EncryptedHeader {
30 const MAGIC_SIZE: usize = 4;
31 pub const STRUCTURE_SIZE: usize = 4
32 + size_of::<u128>()
33 + size_of::<EncryptionNonce>()
34 + size_of::<u32>()
35 + size_of::<u16>()
36 + size_of::<u16>()
37 + size_of::<u64>();
38 const AEAD_BYTES_SIZE: usize = Self::STRUCTURE_SIZE - Self::MAGIC_SIZE - SIGNATURE_SIZE;
39
40 pub fn aead_bytes(&self) -> [u8; Self::AEAD_BYTES_SIZE] {
45 let mut cursor = Cursor::new([0u8; Self::STRUCTURE_SIZE]);
46 self.write(&mut cursor).unwrap();
47 cursor.into_inner()[Self::MAGIC_SIZE + SIGNATURE_SIZE..Self::STRUCTURE_SIZE]
48 .try_into()
49 .unwrap()
50 }
51}
52
53#[binrw::binrw]
54#[derive(Debug)]
55pub struct EncryptedMessage {
56 pub header: EncryptedHeader,
57 #[br(parse_with = binrw::helpers::until_eof)]
58 pub encrypted_message: Vec<u8>,
59}
60
61#[cfg(test)]
62mod tests {
63 use std::io::Cursor;
64
65 use super::*;
66
67 #[test]
68 fn test_parse_encrypted_header() {
69 let header = [
70 0xfdu8, 0x53, 0x4d, 0x42, 0x92, 0x2e, 0xe8, 0xf2, 0xa0, 0x6e, 0x7a, 0xd4, 0x70, 0x22,
71 0xd7, 0x1d, 0xb, 0x2, 0x6b, 0x11, 0xa, 0x57, 0x67, 0x55, 0x6d, 0xa0, 0x23, 0x73, 0x1,
72 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x55, 0x0,
73 0x0, 0x24, 0x0, 0x30, 0x0, 0x0,
74 ];
75 assert_eq!(
76 EncryptedHeader::read(&mut Cursor::new(header)).unwrap(),
77 EncryptedHeader {
78 signature: u128::from_le_bytes([
79 0x92, 0x2e, 0xe8, 0xf2, 0xa0, 0x6e, 0x7a, 0xd4, 0x70, 0x22, 0xd7, 0x1d, 0xb,
80 0x2, 0x6b, 0x11,
81 ]),
82 nonce: [
83 0xa, 0x57, 0x67, 0x55, 0x6d, 0xa0, 0x23, 0x73, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
84 0x0, 0x0,
85 ],
86 original_message_size: 104,
87 session_id: 0x300024000055
88 }
89 )
90 }
91
92 #[test]
93 fn test_write_encrypted_header() {
94 let header = EncryptedHeader {
95 signature: u128::from_le_bytes([
96 0x2a, 0x45, 0x6c, 0x5d, 0xd0, 0xc3, 0x2d, 0xd4, 0x47, 0x85, 0x21, 0xf7, 0xf6, 0xa8,
97 0x87, 0x5b,
98 ]),
99 nonce: [
100 0xbe, 0xe6, 0xbf, 0xe5, 0xa1, 0xe6, 0x7b, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
101 0x0,
102 ],
103 original_message_size: 248,
104 session_id: 0x0000300024000055,
105 };
106 let mut buffer = Vec::new();
107 header.write(&mut Cursor::new(&mut buffer)).unwrap();
108 assert_eq!(
109 buffer,
110 [
111 0xfd, 0x53, 0x4d, 0x42, 0x2a, 0x45, 0x6c, 0x5d, 0xd0, 0xc3, 0x2d, 0xd4, 0x47, 0x85,
112 0x21, 0xf7, 0xf6, 0xa8, 0x87, 0x5b, 0xbe, 0xe6, 0xbf, 0xe5, 0xa1, 0xe6, 0x7b, 0xb1,
113 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0,
114 0x55, 0x0, 0x0, 0x24, 0x0, 0x30, 0x0, 0x0
115 ]
116 );
117 }
118}