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}