ssh_packet/packet/
cipher.rs1use super::{Mac, PACKET_MIN_SIZE};
2
3#[cfg(doc)]
4use super::Packet;
5
6const MIN_PAD_SIZE: usize = 4;
7const MIN_ALIGN: usize = 8;
8
9pub trait CipherCore {
12 type Err: From<binrw::Error> + From<std::io::Error>;
14
15 type Mac: Mac;
17
18 fn mac(&self) -> &Self::Mac;
20
21 fn block_size(&self) -> usize;
23
24 fn padding(&self, payload: usize) -> u8 {
26 let align = self.block_size().max(MIN_ALIGN);
27
28 let size = if self.mac().etm() {
29 std::mem::size_of::<u8>() + payload
30 } else {
31 std::mem::size_of::<u32>() + std::mem::size_of::<u8>() + payload
32 };
33 let padding = align - size % align;
34
35 let padding = if padding < MIN_PAD_SIZE {
36 padding + align
37 } else {
38 padding
39 };
40
41 if size + padding < self.block_size().max(PACKET_MIN_SIZE) {
42 (padding + align) as u8
43 } else {
44 padding as u8
45 }
46 }
47}
48
49pub trait OpeningCipher: CipherCore {
51 fn decrypt<B: AsMut<[u8]>>(&mut self, buf: B) -> Result<(), Self::Err>;
53
54 fn open<B: AsRef<[u8]>>(&mut self, buf: B, mac: Vec<u8>, seq: u32) -> Result<(), Self::Err>;
56
57 fn decompress(&mut self, buf: Vec<u8>) -> Result<Vec<u8>, Self::Err>;
59}
60
61pub trait SealingCipher: CipherCore {
63 fn compress<B: AsRef<[u8]>>(&mut self, buf: B) -> Result<Vec<u8>, Self::Err>;
65
66 fn pad(&mut self, buf: Vec<u8>, padding: u8) -> Result<Vec<u8>, Self::Err>;
69
70 fn encrypt<B: AsMut<[u8]>>(&mut self, buf: B) -> Result<(), Self::Err>;
72
73 fn seal<B: AsRef<[u8]>>(&mut self, buf: B, seq: u32) -> Result<Vec<u8>, Self::Err>;
75}