Skip to main content

ferogram_crypto/
obfuscated.rs

1// Copyright (c) Ankit Chaubey <ankitchaubey.dev@gmail.com>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3//
4// ferogram: async Telegram MTProto client in Rust
5// https://github.com/ankit-chaubey/ferogram
6//
7// If you use or modify this code, keep this notice at the top of your file
8// and include the LICENSE-MIT or LICENSE-APACHE file from this repository:
9// https://github.com/ankit-chaubey/ferogram
10
11#[allow(deprecated)]
12use aes::cipher::{KeyIvInit, StreamCipher, generic_array::GenericArray};
13
14/// AES-256-CTR stream cipher pair for MTProto obfuscated transport.
15pub struct ObfuscatedCipher {
16    #[allow(deprecated)]
17    rx: ctr::Ctr128BE<aes::Aes256>,
18    #[allow(deprecated)]
19    tx: ctr::Ctr128BE<aes::Aes256>,
20}
21
22impl ObfuscatedCipher {
23    /// Build cipher state from the 64-byte random init buffer.
24    #[allow(deprecated)]
25    pub fn new(init: &[u8; 64]) -> Self {
26        let rev: Vec<u8> = init.iter().copied().rev().collect();
27        Self {
28            rx: ctr::Ctr128BE::<aes::Aes256>::new(
29                GenericArray::from_slice(&rev[8..40]),
30                GenericArray::from_slice(&rev[40..56]),
31            ),
32            tx: ctr::Ctr128BE::<aes::Aes256>::new(
33                GenericArray::from_slice(&init[8..40]),
34                GenericArray::from_slice(&init[40..56]),
35            ),
36        }
37    }
38
39    /// Build cipher from explicit key/IV pairs (used when MTProxy secret
40    /// mixing has already been applied externally via SHA-256).
41    #[allow(deprecated)]
42    pub fn from_keys(
43        tx_key: &[u8; 32],
44        tx_iv: &[u8; 16],
45        rx_key: &[u8; 32],
46        rx_iv: &[u8; 16],
47    ) -> Self {
48        Self {
49            tx: ctr::Ctr128BE::<aes::Aes256>::new(
50                GenericArray::from_slice(tx_key),
51                GenericArray::from_slice(tx_iv),
52            ),
53            rx: ctr::Ctr128BE::<aes::Aes256>::new(
54                GenericArray::from_slice(rx_key),
55                GenericArray::from_slice(rx_iv),
56            ),
57        }
58    }
59
60    /// Encrypt outgoing bytes in-place (TX direction).
61    pub fn encrypt(&mut self, buf: &mut [u8]) {
62        self.tx.apply_keystream(buf);
63    }
64
65    /// Decrypt incoming bytes in-place (RX direction).
66    pub fn decrypt(&mut self, buf: &mut [u8]) {
67        self.rx.apply_keystream(buf);
68    }
69}