rtc_dtls/crypto/
crypto_cbc.rs1use aes::cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit};
12use p256::elliptic_curve::subtle::ConstantTimeEq;
13use rand::Rng;
14use std::io::Cursor;
15use std::ops::Not;
16
17use super::padding::DtlsPadding;
18use crate::content::*;
19use crate::prf::*;
20use crate::record_layer::record_layer_header::*;
21use shared::error::*;
22type Aes256CbcEnc = cbc::Encryptor<aes::Aes256>;
23type Aes256CbcDec = cbc::Decryptor<aes::Aes256>;
24
25#[derive(Clone)]
27pub struct CryptoCbc {
28 local_key: Vec<u8>,
29 remote_key: Vec<u8>,
30 write_mac: Vec<u8>,
31 read_mac: Vec<u8>,
32}
33
34impl CryptoCbc {
35 const BLOCK_SIZE: usize = 16;
36 const MAC_SIZE: usize = 20;
37
38 pub fn new(
39 local_key: &[u8],
40 local_mac: &[u8],
41 remote_key: &[u8],
42 remote_mac: &[u8],
43 ) -> Result<Self> {
44 Ok(CryptoCbc {
45 local_key: local_key.to_vec(),
46 write_mac: local_mac.to_vec(),
47
48 remote_key: remote_key.to_vec(),
49 read_mac: remote_mac.to_vec(),
50 })
51 }
52
53 pub fn encrypt(&self, pkt_rlh: &RecordLayerHeader, raw: &[u8]) -> Result<Vec<u8>> {
54 let mut payload = raw[RECORD_LAYER_HEADER_SIZE..].to_vec();
55 let raw = &raw[..RECORD_LAYER_HEADER_SIZE];
56
57 let h = pkt_rlh;
59
60 let mac = prf_mac(
61 h.epoch,
62 h.sequence_number,
63 h.content_type,
64 h.protocol_version,
65 &payload,
66 &self.write_mac,
67 )?;
68 payload.extend_from_slice(&mac);
69
70 let mut iv: Vec<u8> = vec![0; Self::BLOCK_SIZE];
71 rand::rng().fill(iv.as_mut_slice());
72
73 let write_cbc = Aes256CbcEnc::new_from_slices(&self.local_key, &iv)?;
74 let encrypted = write_cbc.encrypt_padded_vec_mut::<DtlsPadding>(&payload);
75
76 let mut r = vec![];
78 r.extend_from_slice(raw);
79 r.extend_from_slice(&iv);
80 r.extend_from_slice(&encrypted);
81
82 let r_len = (r.len() - RECORD_LAYER_HEADER_SIZE) as u16;
83 r[RECORD_LAYER_HEADER_SIZE - 2..RECORD_LAYER_HEADER_SIZE]
84 .copy_from_slice(&r_len.to_be_bytes());
85
86 Ok(r)
87 }
88
89 pub fn decrypt(&self, r: &[u8]) -> Result<Vec<u8>> {
90 let mut reader = Cursor::new(r);
91 let h = RecordLayerHeader::unmarshal(&mut reader)?;
92 if h.content_type == ContentType::ChangeCipherSpec {
93 return Ok(r.to_vec());
95 }
96
97 if r.len() < RECORD_LAYER_HEADER_SIZE + Self::BLOCK_SIZE {
98 return Err(Error::ErrInvalidPacketLength);
99 }
100
101 let body = &r[RECORD_LAYER_HEADER_SIZE..];
102 let iv = &body[0..Self::BLOCK_SIZE];
103 let body = &body[Self::BLOCK_SIZE..];
104
105 if body.is_empty() || !body.len().is_multiple_of(Self::BLOCK_SIZE) {
106 return Err(Error::ErrInvalidPacketLength);
107 }
108
109 let read_cbc = Aes256CbcDec::new_from_slices(&self.remote_key, iv)?;
110
111 let decrypted = read_cbc
112 .decrypt_padded_vec_mut::<DtlsPadding>(body)
113 .map_err(|_| Error::ErrInvalidPacketLength)?;
114
115 let recv_mac = &decrypted[decrypted.len() - Self::MAC_SIZE..];
116 let decrypted = &decrypted[0..decrypted.len() - Self::MAC_SIZE];
117 let mac = prf_mac(
118 h.epoch,
119 h.sequence_number,
120 h.content_type,
121 h.protocol_version,
122 decrypted,
123 &self.read_mac,
124 )?;
125
126 if recv_mac.ct_eq(&mac).not().into() {
127 return Err(Error::ErrInvalidMac);
128 }
129
130 let mut d = Vec::with_capacity(RECORD_LAYER_HEADER_SIZE + decrypted.len());
131 d.extend_from_slice(&r[..RECORD_LAYER_HEADER_SIZE]);
132 d.extend_from_slice(decrypted);
133
134 Ok(d)
135 }
136}