1#![warn(missing_docs)]
2#![allow(incomplete_features)]
3#![feature(slice_as_chunks)]
4#![feature(generic_const_exprs)]
5use aes::Aes256;
15use bincode::{
16 config::{RejectTrailing, VarintEncoding, WithOtherIntEncoding, WithOtherTrailing},
17 DefaultOptions, Options,
18};
19use cipher::{
20 block_padding::Pkcs7, generic_array::GenericArray, BlockDecrypt, BlockEncrypt,
21 KeyInit,
22};
23use rand::random;
24use serde::{de::DeserializeOwned, Deserialize, Serialize};
25use std::error::Error;
26use std::{
27 collections::{HashMap, VecDeque},
28 fmt::Display,
29};
30
31#[derive(Debug)]
35pub enum CovertError {
36 DecryptionError,
38 InvalidHash,
40 DeserializeError,
42}
43
44impl Display for CovertError {
45 #[cfg(not(debug_assertions))]
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 write!(f, "")
48 }
49
50 #[cfg(debug_assertions)]
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 match self {
53 CovertError::DecryptionError => write!(f, "Decryption error"),
54 CovertError::InvalidHash => write!(f, "Invalid hash error"),
55 CovertError::DeserializeError => write!(f, "Deserialization error"),
56 }
57 }
58}
59
60impl Error for CovertError {
61 fn source(&self) -> Option<&(dyn Error + 'static)> {
62 None
63 }
64
65 fn description(&self) -> &str {
66 ""
67 }
68
69 fn cause(&self) -> Option<&dyn Error> {
70 self.source()
71 }
72}
73
74#[derive(Deserialize, Serialize, Debug)]
75struct CovertPacket {
76 hash: u8,
77 stream: u16,
78 syn: u32,
79 want: u32,
80 last: bool,
81 payload: Vec<u8>,
82 pad: Vec<u8>,
83} impl CovertPacket {
86 fn new(stream: u16, syn: u32, last: bool, payload: &[u8], blocks: usize) -> Self {
87 let buf_size = (blocks * 16) - 18;
88 let pad = vec![0u8; buf_size - payload.len()];
89 let pad: Vec<u8> = pad.iter().map(|_| random()).collect();
90
91 Self {
92 hash: 0,
93 stream,
94 syn,
95 want: 0,
96 last,
97 payload: payload.to_vec(),
98 pad,
99 }
100 }
101}
102
103struct CovertStream<T> {
104 out_bound_packet_cache: VecDeque<CovertPacket>,
105 in_bound_packet_cache: VecDeque<CovertPacket>,
106 message_cache: VecDeque<T>,
107 out_count: u32,
108 out_syn: u32,
109 in_syn: u32,
110}
111
112pub struct CovertChannel<T, const BLOCKS: usize>
120where
121 T: DeserializeOwned + Serialize,
122{
123 engine: Aes256,
124 encoder: WithOtherTrailing<
125 WithOtherIntEncoding<DefaultOptions, VarintEncoding>,
126 RejectTrailing,
127 >,
128 streams: HashMap<u16, CovertStream<T>>,
129}
130
131impl<T, const BLOCKS: usize> CovertChannel<T, BLOCKS>
132where
133 T: DeserializeOwned + Serialize,
134{
135 pub fn new(key: [u8; 32]) -> CovertChannel<T, BLOCKS> {
137 let encoder = bincode::DefaultOptions::new()
138 .with_varint_encoding()
139 .reject_trailing_bytes();
140 CovertChannel {
142 encoder,
143 engine: Aes256::new(&GenericArray::from(key)),
144 streams: HashMap::new(),
145 }
146 }
147
148 pub fn get_message(&mut self, stream_id: u16) -> Option<T> {
151 let stream = self.streams.get_mut(&stream_id)?;
152 stream.message_cache.pop_front()
153 }
154
155 pub fn put_message(&mut self, msg: T, stream_id: u16) -> ()
157 where
158 [(); (BLOCKS * 16) - 18]:,
159 {
160 let encode = self.encoder;
161 let stream = self.get_stream_by_id(stream_id);
162 let res = encode.serialize(&msg).unwrap();
163 let (parts, end) = res.as_chunks::<{ (BLOCKS * 16) - 18 }>();
164 for part in parts {
165 let new_packet = CovertPacket::new(
166 stream_id,
167 stream.out_count,
168 false,
169 part.as_slice(),
170 BLOCKS,
171 );
172 stream.out_count += 1;
173 stream.out_bound_packet_cache.push_back(new_packet);
174 }
175 if end.len() != 0 {
176 let last_packet =
177 CovertPacket::new(stream_id, stream.out_count, true, end, BLOCKS);
178 stream.out_bound_packet_cache.push_back(last_packet);
179 stream.out_count += 1;
180 } else {
181 stream.out_bound_packet_cache.back_mut().unwrap().last = true;
182 }
183 }
184
185 pub fn get_packet(&mut self, stream_id: u16) -> Vec<u8> {
190 let encode = self.encoder;
191 let stream = self.get_stream_by_id(stream_id);
192 if stream.out_bound_packet_cache.len() == 0 {
193 stream.out_bound_packet_cache.push_front(CovertPacket::new(
194 stream_id,
195 stream.out_count,
196 false,
197 &[],
198 BLOCKS,
199 ));
200 stream.out_count += 1;
201 }
202 let out = stream.out_bound_packet_cache.front_mut().unwrap();
203 out.want = stream.in_syn;
204 let mut tmp = encode.serialize(out).unwrap();
205 let hash = crc32fast::hash(&tmp).to_le_bytes()[0];
206 tmp[0] = hash;
207 let done = self.engine.encrypt_padded_vec::<Pkcs7>(&tmp);
208 return done;
209 }
210
211 pub fn put_packet(&mut self, pkt: &[u8]) -> Result<(u16, bool), CovertError> {
214 let encode = self.encoder;
215 let mut tmp = self
216 .engine
217 .decrypt_padded_vec::<Pkcs7>(pkt)
218 .or(Err(CovertError::DecryptionError))?;
219 let hash = tmp[0];
220 tmp[0] = 0;
221 let actual = crc32fast::hash(&tmp).to_le_bytes()[0];
222 if hash != actual {
223 return Err(CovertError::InvalidHash);
224 };
225 let in_packet = encode
226 .deserialize::<CovertPacket>(&tmp)
227 .or(Err(CovertError::DeserializeError))?;
228
229 let stream_id = in_packet.stream;
230 let mut stream = self.get_stream_by_id(stream_id);
231
232 stream.out_syn = Ord::max(stream.out_syn, in_packet.want);
234 stream
235 .out_bound_packet_cache
236 .retain(|item| item.syn >= stream.out_syn);
237 if in_packet.syn == stream.in_syn {
239 stream.in_syn += 1;
240 let is_last = in_packet.last;
241 stream.in_bound_packet_cache.push_back(in_packet);
242 if is_last {
243 let mut payload: Vec<u8> = stream
244 .in_bound_packet_cache
245 .drain(..)
246 .map(|i| i.payload)
247 .flatten()
248 .collect();
249 let in_message = encode
250 .deserialize::<T>(&mut payload)
251 .or(Err(CovertError::DeserializeError))?;
252 stream.message_cache.push_back(in_message);
253 return Ok((stream_id, true));
254 }
255 };
256 return Ok((stream_id, false));
257 }
258
259 pub fn packets_in_queue(&self, stream_id: u16) -> (usize, usize) {
261 if let Some(stream) = self.streams.get(&stream_id) {
262 return (
263 stream.in_bound_packet_cache.len(),
264 stream.out_bound_packet_cache.len(),
265 );
266 }
267 return (0, 0);
268 }
269
270 fn get_stream_by_id(&mut self, stream_id: u16) -> &mut CovertStream<T> {
271 if !self.streams.contains_key(&stream_id) {
272 let new_stream = CovertStream {
273 out_bound_packet_cache: VecDeque::new(),
274 in_bound_packet_cache: VecDeque::new(),
275 message_cache: VecDeque::new(),
276 out_count: 0,
277 out_syn: 0,
278 in_syn: 0,
279 };
280 self.streams.insert(stream_id, new_stream);
281 }
282 self.streams.get_mut(&stream_id).unwrap()
283 }
284}
285
286#[cfg(test)]
287mod test;