1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use std::io::Cursor;
use crate::content::*;
use crate::error::Error;
use crate::prf::*;
use crate::record_layer::record_layer_header::*;
use aes::Aes256;
use block_modes::block_padding::Pkcs7;
use block_modes::{BlockMode, Cbc};
type Aes256Cbc = Cbc<Aes256, Pkcs7>;
#[derive(Clone)]
pub struct CryptoCbc {
write_cbc: Aes256Cbc,
read_cbc: Aes256Cbc,
write_mac: Vec<u8>,
read_mac: Vec<u8>,
}
impl CryptoCbc {
const BLOCK_SIZE: usize = 32;
pub fn new(
local_key: &[u8],
local_write_iv: &[u8],
local_mac: &[u8],
remote_key: &[u8],
remote_write_iv: &[u8],
remote_mac: &[u8],
) -> Result<Self, Error> {
Ok(CryptoCbc {
write_cbc: Aes256Cbc::new_var(local_key, local_write_iv)?,
write_mac: local_mac.to_vec(),
read_cbc: Aes256Cbc::new_var(remote_key, remote_write_iv)?,
read_mac: remote_mac.to_vec(),
})
}
pub fn encrypt(&self, pkt_rlh: &RecordLayerHeader, raw: &[u8]) -> Result<Vec<u8>, Error> {
let mut payload = raw[RECORD_LAYER_HEADER_SIZE..].to_vec();
let raw = &raw[..RECORD_LAYER_HEADER_SIZE];
let h = pkt_rlh;
let mac = prf_mac(
h.epoch,
h.sequence_number,
h.content_type,
h.protocol_version,
&payload,
&self.write_mac,
)?;
payload.extend_from_slice(&mac);
let encrypted = self.write_cbc.clone().encrypt_vec(&payload);
let mut r = vec![];
r.extend_from_slice(raw);
r.extend_from_slice(&encrypted);
let r_len = (r.len() - RECORD_LAYER_HEADER_SIZE) as u16;
r[RECORD_LAYER_HEADER_SIZE - 2..RECORD_LAYER_HEADER_SIZE]
.copy_from_slice(&r_len.to_be_bytes());
Ok(r)
}
pub fn decrypt(&self, r: &[u8]) -> Result<Vec<u8>, Error> {
let mut reader = Cursor::new(r);
let h = RecordLayerHeader::unmarshal(&mut reader)?;
if h.content_type == ContentType::ChangeCipherSpec {
return Ok(r.to_vec());
}
let body = &r[RECORD_LAYER_HEADER_SIZE..];
let decrypted = self.read_cbc.clone().decrypt_vec(body)?;
let mut d = Vec::with_capacity(RECORD_LAYER_HEADER_SIZE + decrypted.len());
d.extend_from_slice(&r[..RECORD_LAYER_HEADER_SIZE]);
d.extend_from_slice(&decrypted);
Ok(d)
}
}