ssh/algorithm/encryption/
chacha20_poly1305_openssh.rs1use crate::algorithm::hash::Hash;
2use crate::algorithm::mac::Mac;
3use crate::error::SshError;
4use crate::{algorithm::encryption::Encryption, error::SshResult};
5use ring::aead::chacha20_poly1305_openssh::{OpeningKey, SealingKey};
6
7const KEY_SIZE: usize = 64;
8const IV_SIZE: usize = 0;
9const BLOCK_SIZE: usize = 0;
10const MAC_SIZE: usize = 16;
11
12pub(super) struct ChaCha20Poly1305 {
13 client_key: SealingKey,
14 server_key: OpeningKey,
15}
16
17impl Encryption for ChaCha20Poly1305 {
18 fn bsize(&self) -> usize {
19 BLOCK_SIZE
20 }
21
22 fn iv_size(&self) -> usize {
23 IV_SIZE
24 }
25
26 fn new(hash: Hash, _mac: Box<dyn Mac>) -> ChaCha20Poly1305 {
27 let (ck, sk) = hash.mix_ek(KEY_SIZE);
28 let mut sealing_key = [0_u8; KEY_SIZE];
29 let mut opening_key = [0_u8; KEY_SIZE];
30 sealing_key.copy_from_slice(&ck);
31 opening_key.copy_from_slice(&sk);
32
33 ChaCha20Poly1305 {
34 client_key: SealingKey::new(&sealing_key),
35 server_key: OpeningKey::new(&opening_key),
36 }
37 }
38
39 fn encrypt(&mut self, sequence_number: u32, buf: &mut Vec<u8>) {
40 let mut tag = [0_u8; MAC_SIZE];
41 self.client_key
42 .seal_in_place(sequence_number, buf, &mut tag);
43 buf.append(&mut tag.to_vec());
44 }
45
46 fn decrypt(&mut self, sequence_number: u32, buf: &mut [u8]) -> SshResult<Vec<u8>> {
47 let mut packet_len_slice = [0_u8; 4];
48 let len = &buf[..4];
49 packet_len_slice.copy_from_slice(len);
50 let packet_len_slice = self
51 .server_key
52 .decrypt_packet_length(sequence_number, packet_len_slice);
53 let packet_len = u32::from_be_bytes(packet_len_slice);
54 let (buf, tag_) = buf.split_at_mut((packet_len + 4) as usize);
55 let mut tag = [0_u8; MAC_SIZE];
56 tag.copy_from_slice(tag_);
57 match self.server_key.open_in_place(sequence_number, buf, &tag) {
58 Ok(result) => Ok([&packet_len_slice[..], result].concat()),
59 Err(_) => Err(SshError::EncryptionError(
60 "Failed to decrypt the server traffic".to_owned(),
61 )),
62 }
63 }
64
65 fn packet_len(&mut self, sequence_number: u32, buf: &[u8]) -> usize {
66 let mut packet_len_slice = [0_u8; 4];
67 packet_len_slice.copy_from_slice(&buf[..4]);
68 let packet_len_slice = self
69 .server_key
70 .decrypt_packet_length(sequence_number, packet_len_slice);
71 u32::from_be_bytes(packet_len_slice) as usize + 4
72 }
73
74 fn data_len(&mut self, sequence_number: u32, buf: &[u8]) -> usize {
75 let packet_len = self.packet_len(sequence_number, buf);
76 packet_len + MAC_SIZE
77 }
78
79 fn no_pad(&self) -> bool {
80 true
81 }
82}