smb_msg/
encrypted.rs

1//! Encrypted messages
2
3use std::io::Cursor;
4
5use binrw::prelude::*;
6const SIGNATURE_SIZE: usize = 16;
7
8/// The nonce used for encryption.
9/// Depending on the encryption algorithm, the nonce may be trimmed to a smaller size when used,
10/// or padded with zeroes to match the required size. When transmitted, the full 16 bytes are used.
11pub 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)] // MUST be set to 1.
24    #[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    /// The bytes to use as the additional data for the AEAD out of this header.
41    /// Make sure to call it after all fields (except signature) are finalized.
42    ///
43    /// Returns (according to MS-SMB2) the bytes of the header, excluding the magic and the signature.
44    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}