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
use crate::cryptography::{hmac_md5, rc4_decrypt, rc4_encrypt};
use crate::{Error, Result};
pub fn encrypt(
key: &[u8],
key_usage: i32,
timestamp: &[u8],
preamble: &[u8],
) -> Vec<u8> {
let mut plaintext: Vec<u8> = Vec::new();
plaintext.append(&mut preamble.to_vec());
plaintext.append(&mut timestamp.to_vec());
let ki = hmac_md5(key, &key_usage.to_le_bytes());
let mut cksum = hmac_md5(&ki, &plaintext);
let ke = hmac_md5(&ki, &cksum);
let mut enc = rc4_encrypt(&ke, &plaintext);
cksum.append(&mut enc);
return cksum;
}
pub fn decrypt(
key: &[u8],
key_usage: i32,
ciphertext: &[u8],
) -> Result<Vec<u8>> {
if ciphertext.len() < 24 {
return Err(Error::DecryptionError(
"Ciphertext too short".to_string(),
))?;
}
let cksum = &ciphertext[0..16];
let basic_ciphertext = &ciphertext[16..];
let ki = hmac_md5(key, &key_usage.to_le_bytes());
let ke = hmac_md5(&ki, &cksum);
let plaintext = rc4_decrypt(&ke, &basic_ciphertext);
let plaintext_cksum = hmac_md5(&ki, &plaintext);
if cksum != &plaintext_cksum[..] {
return Err(Error::DecryptionError(
"Hmac integrity failure".to_string(),
))?;
}
return Ok(plaintext[8..].to_vec());
}