kasimir_sys/
lib.rs

1use std::io::{Read, Write};
2
3pub fn decrypt_hs100(data: &mut [u8]) {
4    let mut key = 171u8;
5    for b in data {
6        if *b != 0 {
7            *b = *b ^ key;
8            key = *b ^ key;
9        }
10    }
11}
12
13pub fn encrypt_hs100(data: &mut [u8]) {
14    let mut key = 171u8;
15    for b in data {
16        if *b != 0 {
17            *b = *b ^ key;
18            key = *b;
19        }
20    }
21}
22
23pub fn read_hs100_str<T: Read + ?Sized>(stream: &mut T) -> std::io::Result<String> {
24    let mut len = [0; 4];
25
26    stream.read(&mut len)?;
27
28    let len = ((len[0] as usize) << 24)
29        + ((len[1] as usize) << 16)
30        + ((len[2] as usize) << 8)
31        + (len[3] as usize);
32
33    let mut buf: Vec<u8> = vec![0; len];
34    stream.read_exact(&mut buf)?;
35
36    decrypt_hs100(&mut buf);
37
38    let mut result = std::str::from_utf8(&buf).unwrap().to_owned();
39    result.truncate(len);
40
41    Ok(result)
42}
43
44pub fn write_hs100_str<T: Write + ?Sized>(
45    stream: &mut T,
46    mut message: String,
47) -> std::io::Result<()> {
48    let mut len = [0; 4];
49
50    len[3] = (message.len() % 0xFF) as u8;
51    len[2] = ((message.len() >> 8) % 0xFF) as u8;
52    len[1] = ((message.len() >> 16) % 0xFF) as u8;
53    len[0] = ((message.len() >> 24) % 0xFF) as u8;
54
55    let bytes = unsafe { message.as_bytes_mut() };
56    encrypt_hs100(bytes);
57
58    stream.write(&len)?;
59    stream.write(bytes)?;
60
61    Ok(())
62}
63
64#[cfg(test)]
65mod tests {
66    #[test]
67    fn encrytion() {
68        let plaintext: &mut [u8] = &mut br#"{"system":{"get_sysinfo":{}}}"#.clone();
69        let cyphertext = [
70            208, 242, 129, 248, 139, 255, 154, 247, 213, 239, 148, 182, 209, 180, 192, 159, 236,
71            149, 230, 143, 225, 135, 232, 202, 240, 139, 246, 139, 246,
72        ];
73
74        super::encrypt_hs100(plaintext);
75        assert_eq!(&plaintext, &cyphertext);
76    }
77
78    #[test]
79    fn decryption() {
80        let plaintext = br#"{"system":{"get_sysinfo":{}}}"#;
81        let cyphertext: &mut [u8] = &mut [
82            208, 242, 129, 248, 139, 255, 154, 247, 213, 239, 148, 182, 209, 180, 192, 159, 236,
83            149, 230, 143, 225, 135, 232, 202, 240, 139, 246, 139, 246,
84        ]
85        .clone();
86
87        super::decrypt_hs100(cyphertext);
88        assert_eq!(&cyphertext, &plaintext);
89    }
90
91    #[test]
92    fn encrytion_roundtrip() {
93        let original = br#"{"system":{"get_sysinfo":{}}}"#;
94        let modified: &mut [u8] = &mut br#"{"system":{"get_sysinfo":{}}}"#.clone();
95
96        super::encrypt_hs100(modified);
97        super::decrypt_hs100(modified);
98        assert_eq!(&original, &modified);
99    }
100
101    #[test]
102    fn read() {
103        let plaintext = r#"{"system":{"get_sysinfo":{}}}"#.to_string();
104        let cyphertext: &[u8] = &[
105            0, 0, 0, 29, 208, 242, 129, 248, 139, 255, 154, 247, 213, 239, 148, 182, 209, 180, 192,
106            159, 236, 149, 230, 143, 225, 135, 232, 202, 240, 139, 246, 139, 246,
107        ];
108
109        let result = super::read_hs100_str(&mut cyphertext.as_ref()).unwrap();
110        assert_eq!(&result, &plaintext);
111    }
112
113    #[test]
114    fn write() {
115        let plaintext = r#"{"system":{"get_sysinfo":{}}}"#.to_string();
116        let cyphertext = [
117            0, 0, 0, 29, 208, 242, 129, 248, 139, 255, 154, 247, 213, 239, 148, 182, 209, 180, 192,
118            159, 236, 149, 230, 143, 225, 135, 232, 202, 240, 139, 246, 139, 246,
119        ];
120
121        let mut buffer: Vec<u8> = Vec::new();
122        super::write_hs100_str(&mut buffer, plaintext).unwrap();
123        assert_eq!(&buffer, &cyphertext);
124    }
125}