layer_client/
transport_obfuscated.rs1use sha2::{Sha256, Digest};
11use tokio::io::{AsyncReadExt, AsyncWriteExt};
12use tokio::net::TcpStream;
13use crate::InvocationError;
14
15pub struct ObfCipher {
20 key: [u8; 32],
21 iv: [u8; 16],
22 buf: Vec<u8>,
23 pos: usize,
24}
25
26impl ObfCipher {
27 pub fn new(key: [u8; 32], iv: [u8; 16]) -> Self {
28 Self { key, iv, buf: Vec::new(), pos: 0 }
29 }
30
31 pub fn fill(&mut self) {
33 let mut h = Sha256::new();
34 h.update(&self.key);
35 h.update(&self.iv);
36 h.update(&self.buf);
37 let block = h.finalize();
38 self.buf.extend_from_slice(&block);
39 }
40
41 pub fn apply(&mut self, data: &mut [u8]) {
43 for byte in data.iter_mut() {
44 while self.pos >= self.buf.len() {
45 self.fill();
46 }
47 *byte ^= self.buf[self.pos];
48 self.pos += 1;
49 }
50 }
51}
52
53pub struct ObfuscatedStream {
60 stream: TcpStream,
61 enc: ObfCipher,
62 dec: ObfCipher,
63}
64
65impl ObfuscatedStream {
66 pub async fn connect(addr: &str, proxy_secret: Option<&[u8; 16]>) -> Result<Self, InvocationError> {
71 let stream = TcpStream::connect(addr).await?;
72 Self::handshake(stream, proxy_secret).await
73 }
74
75 async fn handshake(
76 mut stream: TcpStream,
77 proxy_secret: Option<&[u8; 16]>,
78 ) -> Result<Self, InvocationError> {
79 let mut nonce = [0u8; 64];
81 getrandom::getrandom(&mut nonce).map_err(|_| InvocationError::Deserialize("getrandom failed".into()))?;
82
83 nonce[56] = 0xef;
86 nonce[57] = 0xef;
87 nonce[58] = 0xef;
88 nonce[59] = 0xef;
89
90 let (enc_key, enc_iv, dec_key, dec_iv) = derive_keys(&nonce, proxy_secret);
92
93 let mut enc = ObfCipher::new(enc_key, enc_iv);
94 let dec = ObfCipher::new(dec_key, dec_iv);
95
96 let mut encrypted_header = nonce;
98 enc.apply(&mut encrypted_header[56..]); stream.write_all(&encrypted_header).await?;
100
101 log::info!("[obfuscated] Handshake sent");
102
103 Ok(Self { stream, enc, dec })
104 }
105
106 pub async fn send(&mut self, data: &[u8]) -> Result<(), InvocationError> {
108 let words = data.len() / 4;
109 let mut header = if words < 0x7f {
110 vec![words as u8]
111 } else {
112 vec![0x7f, (words & 0xff) as u8, ((words >> 8) & 0xff) as u8, ((words >> 16) & 0xff) as u8]
113 };
114
115 self.enc.apply(&mut header);
117 let mut payload = data.to_vec();
118 self.enc.apply(&mut payload);
119
120 self.stream.write_all(&header).await?;
121 self.stream.write_all(&payload).await?;
122 Ok(())
123 }
124
125 pub async fn recv(&mut self) -> Result<Vec<u8>, InvocationError> {
127 let mut h = [0u8; 1];
128 self.stream.read_exact(&mut h).await?;
129 self.dec.apply(&mut h);
130
131 let words = if h[0] < 0x7f {
132 h[0] as usize
133 } else {
134 let mut b = [0u8; 3];
135 self.stream.read_exact(&mut b).await?;
136 self.dec.apply(&mut b);
137 b[0] as usize | (b[1] as usize) << 8 | (b[2] as usize) << 16
138 };
139
140 let mut buf = vec![0u8; words * 4];
141 self.stream.read_exact(&mut buf).await?;
142 self.dec.apply(&mut buf);
143 Ok(buf)
144 }
145}
146
147pub fn derive_keys(
153 nonce: &[u8; 64],
154 secret: Option<&[u8; 16]>,
155) -> ([u8; 32], [u8; 16], [u8; 32], [u8; 16]) {
156 let (enc_key, enc_iv) = derive_one(&nonce[8..40], &nonce[40..56], secret);
157 let mut rev = *nonce;
159 rev[8..40].reverse();
160 rev[40..56].reverse();
161 let (dec_key, dec_iv) = derive_one(&rev[8..40], &rev[40..56], secret);
162 (enc_key, enc_iv, dec_key, dec_iv)
163}
164
165fn derive_one(key_src: &[u8], iv_src: &[u8], secret: Option<&[u8; 16]>) -> ([u8; 32], [u8; 16]) {
166 let mut key = [0u8; 32];
167 let mut iv = [0u8; 16];
168 if let Some(s) = secret {
169 let mut h = Sha256::new();
170 h.update(key_src);
171 h.update(s);
172 key.copy_from_slice(&h.finalize());
173 } else {
174 let len = key_src.len().min(32);
175 key[..len].copy_from_slice(&key_src[..len]);
176 }
177 let len = iv_src.len().min(16);
178 iv[..len].copy_from_slice(&iv_src[..len]);
179 (key, iv)
180}