srt_protocol/protocol/encryption/
key.rs1use std::{
2 array::TryFromSliceError,
3 convert::TryInto,
4 fmt::{self, Debug, Formatter},
5 ops::Deref,
6};
7
8use aes::{Aes128, Aes192, Aes256};
9use cipher::KeyInit;
10use hmac::Hmac;
11use rand::{rngs::OsRng, RngCore};
12use sha1::Sha1;
13
14use crate::{
15 packet::SeqNumber,
16 settings::{KeySettings, KeySize, Passphrase},
17};
18
19use super::wrap;
20
21#[derive(Clone, Eq, PartialEq)]
22pub struct Salt([u8; 16]);
23
24impl Salt {
25 pub fn new_random() -> Self {
26 let mut salt = [0; 16];
27 OsRng.fill_bytes(&mut salt[..]);
28 Self(salt)
29 }
30
31 pub fn try_from(bytes: &[u8]) -> Result<Salt, TryFromSliceError> {
32 Ok(Salt(bytes[..].try_into()?))
33 }
34
35 pub fn generate_strean_iv_for(&self, seq_number: SeqNumber) -> StreamInitializationVector {
36 let salt = self.0;
37 let mut out = [0; 16];
52 out[0..14].copy_from_slice(&salt[..14]);
53
54 for (i, b) in seq_number.0.to_be_bytes().iter().enumerate() {
55 out[i + 10] ^= *b;
56 }
57
58 StreamInitializationVector(out)
62 }
63
64 pub fn as_slice(&self) -> &[u8] {
65 &self.0
66 }
67}
68
69impl Debug for Salt {
70 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
71 write!(f, "Salt(0x{})", hex::encode_upper(self.0))
72 }
73}
74
75#[derive(Clone, Eq, PartialEq)]
76pub struct StreamInitializationVector([u8; 16]);
77
78impl StreamInitializationVector {
79 pub fn try_from(slice: &[u8]) -> Result<Self, TryFromSliceError> {
80 Ok(StreamInitializationVector(slice[..].try_into()?))
81 }
82
83 pub fn as_bytes(&self) -> &[u8] {
84 &self.0
85 }
86}
87
88impl Debug for StreamInitializationVector {
89 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
90 write!(f, "StreamIV(0x{})", hex::encode_upper(self.0))
91 }
92}
93
94#[derive(Clone, Eq, PartialEq)]
95pub struct WrapInitializationVector([u8; 8]);
96
97impl WrapInitializationVector {
98 pub fn try_from(slice: &[u8]) -> Result<Self, TryFromSliceError> {
99 Ok(WrapInitializationVector(slice[..].try_into()?))
100 }
101}
102
103impl Debug for WrapInitializationVector {
104 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
105 write!(f, "KeyIV(0x{})", hex::encode_upper(self.0))
106 }
107}
108
109#[derive(Clone, Eq, PartialEq)]
110pub enum EncryptionKey {
111 Bytes16([u8; 16]),
112 Bytes24([u8; 24]),
113 Bytes32([u8; 32]),
114}
115
116impl EncryptionKey {
117 pub fn new_random(size: KeySize) -> Self {
118 use EncryptionKey::*;
119 fn new_key<const N: usize>() -> [u8; N] {
120 let mut key = [0u8; N];
121 OsRng.fill_bytes(&mut key[..]);
122 key
123 }
124 match size {
125 KeySize::AES128 => Bytes16(new_key()),
126 KeySize::AES192 => Bytes24(new_key()),
127 KeySize::AES256 => Bytes32(new_key()),
128 KeySize::Unspecified => Bytes16(new_key()),
129 }
130 }
131
132 pub fn try_from(bytes: &[u8]) -> Result<EncryptionKey, TryFromSliceError> {
133 use EncryptionKey::*;
134 match bytes.len() {
135 16 => Ok(Bytes16(bytes[..].try_into()?)),
136 24 => Ok(Bytes24(bytes[..].try_into()?)),
137 _ => Ok(Bytes32(bytes[..].try_into()?)),
138 }
139 }
140
141 #[allow(clippy::len_without_is_empty)]
142 pub fn len(&self) -> usize {
143 use EncryptionKey::*;
144 match self {
145 Bytes16(key) => key.len(),
146 Bytes24(key) => key.len(),
147 Bytes32(key) => key.len(),
148 }
149 }
150
151 pub fn as_bytes(&self) -> &[u8] {
152 use EncryptionKey::*;
153 match self {
154 Bytes16(key) => &key[..],
155 Bytes24(key) => &key[..],
156 Bytes32(key) => &key[..],
157 }
158 }
159}
160
161impl fmt::Debug for EncryptionKey {
162 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
163 use EncryptionKey::*;
164 match self {
165 Bytes16(_) => f.debug_struct("EncryptionKey::Bytes16"),
166 Bytes24(_) => f.debug_struct("EncryptionKey::Bytes24"),
167 Bytes32(_) => f.debug_struct("EncryptionKey::Bytes32"),
168 }
169 .finish()
170 }
171}
172
173#[derive(Clone, Eq, PartialEq)]
174pub struct KeyEncryptionKey(EncryptionKey);
175
176impl KeyEncryptionKey {
177 pub fn new(key_settings: &KeySettings, salt: &Salt) -> Self {
178 let key_size = key_settings.key_size;
179 let passphrase = &key_settings.passphrase;
180
181 fn calculate_pbkdf2(passphrase: &Passphrase, salt: &Salt, key: &mut [u8]) {
189 let salt = salt.0;
190 const ROUNDS: u32 = 2048;
192 let salt_len = usize::min(8, salt.len());
193 pbkdf2::pbkdf2::<Hmac<Sha1>>(
194 passphrase.as_bytes(),
195 &salt[salt.len() - salt_len..], ROUNDS,
197 &mut *key,
198 )
199 .unwrap();
200 }
201
202 fn new_key<const N: usize>(passphrase: &Passphrase, salt: &Salt) -> [u8; N] {
203 let mut key = [0u8; N];
204 calculate_pbkdf2(passphrase, salt, &mut key);
205 key
206 }
207
208 use EncryptionKey::*;
209 let key = match key_size {
210 KeySize::AES128 => Bytes16(new_key(passphrase, salt)),
211 KeySize::AES192 => Bytes24(new_key(passphrase, salt)),
212 KeySize::AES256 => Bytes32(new_key(passphrase, salt)),
213 KeySize::Unspecified => Bytes16(new_key(passphrase, salt)),
214 };
215
216 KeyEncryptionKey(key)
217 }
218
219 pub fn encrypt_wrapped_keys(&self, keys: &[u8]) -> Vec<u8> {
220 let mut encrypted_keys = vec![0; keys.len() + 8];
221 use EncryptionKey::*;
222 match &self.0 {
223 Bytes16(key) => wrap::aes_wrap(
224 &Aes128::new(key[..].into()),
225 None,
226 &mut encrypted_keys,
227 keys,
228 ),
229 Bytes24(key) => wrap::aes_wrap(
230 &Aes192::new(key[..].into()),
231 None,
232 &mut encrypted_keys,
233 keys,
234 ),
235 Bytes32(key) => wrap::aes_wrap(
236 &Aes256::new(key[..].into()),
237 None,
238 &mut encrypted_keys,
239 keys,
240 ),
241 }
242 encrypted_keys
243 }
244
245 pub fn decrypt_wrapped_keys(
246 &self,
247 wrapped_keys: &[u8],
248 ) -> Result<Vec<u8>, WrapInitializationVector> {
249 use EncryptionKey::*;
250 let mut keys = vec![0; wrapped_keys.len() - 8];
251 let mut iv = [0; 8];
252 match &self.0 {
253 Bytes16(key) => wrap::aes_unwrap(
254 &Aes128::new(key[..].into()),
255 &mut iv,
256 &mut keys,
257 wrapped_keys,
258 ),
259 Bytes24(key) => wrap::aes_unwrap(
260 &Aes192::new(key[..].into()),
261 &mut iv,
262 &mut keys,
263 wrapped_keys,
264 ),
265 Bytes32(key) => wrap::aes_unwrap(
266 &Aes256::new(key[..].into()),
267 &mut iv,
268 &mut keys,
269 wrapped_keys,
270 ),
271 }
272 if iv != wrap::DEFAULT_IV {
273 return Err(WrapInitializationVector(iv));
274 }
275 Ok(keys)
276 }
277}
278
279impl Deref for KeyEncryptionKey {
280 type Target = EncryptionKey;
281
282 fn deref(&self) -> &Self::Target {
283 &self.0
284 }
285}
286
287impl fmt::Debug for KeyEncryptionKey {
288 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
289 use EncryptionKey::*;
290 match &self.0 {
291 Bytes16(_) => f.debug_struct("KeyEncryptionKey::Bytes16"),
292 Bytes24(_) => f.debug_struct("KeyEncryptionKey::Bytes24"),
293 Bytes32(_) => f.debug_struct("KeyEncryptionKey::Bytes32"),
294 }
295 .finish()
296 }
297}
298
299#[cfg(test)]
300mod test {
301 use super::*;
302
303 #[test]
304 fn kek_generate() {
305 let key_settings = KeySettings {
307 key_size: KeySize::AES128,
308 passphrase: "password123".into(),
309 };
310 let expected_kek = &hex::decode(b"08F2758F41E4244D00057C9CEBEB95FC").unwrap()[..];
311 let salt =
312 Salt::try_from(&hex::decode(b"7D59759C2B1A3F0B06C7028790C81C7D").unwrap()[..]).unwrap();
313
314 let kek = KeyEncryptionKey::new(&key_settings, &salt);
315
316 assert_eq!(kek.0.as_bytes(), expected_kek);
317
318 assert_eq!(format!("{kek:?}"), "KeyEncryptionKey::Bytes16");
320 assert_eq!(format!("{:?}", kek.deref()), "EncryptionKey::Bytes16");
321
322 assert_ne!(Salt::new_random(), Salt::new_random());
323 }
324
325 #[test]
326 fn generate_iv() {
327 let salt =
329 Salt::try_from(&hex::decode(b"87647f8a2361fb1a9e692de576985949").unwrap()[..]).unwrap();
330 let expected_iv = StreamInitializationVector::try_from(
331 &hex::decode(b"87647f8a2361fb1a9e6907af1b810000").unwrap()[..],
332 )
333 .unwrap();
334
335 let iv = salt.generate_strean_iv_for(SeqNumber(709520665));
336
337 assert_eq!(iv, expected_iv);
338
339 assert_eq!(
340 format!("{iv:?}"),
341 "StreamIV(0x87647F8A2361FB1A9E6907AF1B810000)"
342 );
343 assert_eq!(
344 format!("{salt:?}"),
345 "Salt(0x87647F8A2361FB1A9E692DE576985949)"
346 );
347
348 assert_ne!(Salt::new_random(), Salt::new_random());
349 }
350}