radius_rust/tools/
mod.rs

1//! Various helper functions, that are used by RADIUS Client & Server to encode/decode information
2//! inside RADIUS packet
3//! They are also available to crate users to prepare data before it is packed into RADIUS packet
4
5
6use md5::{Digest, Md5};
7
8use std::convert::TryInto;
9use std::fmt::Write;
10use std::net::{ Ipv4Addr, Ipv6Addr };
11use std::str::FromStr;
12
13use crate::protocol::error::RadiusError;
14
15
16/// Converts IPv6 Address string into vector of bytes
17///
18/// Should be used for any Attribute of type **ipv6addr** or **ipv6prefix** to ensure value is encoded correctly
19pub fn ipv6_string_to_bytes(ipv6: &str) -> Result<Vec<u8>, RadiusError> {
20    let parsed_ipv6: Vec<&str> = ipv6.split('/').collect();
21    let mut bytes: Vec<u8>     = Vec::with_capacity(18);
22    let ipv6_address           = Ipv6Addr::from_str(parsed_ipv6[0]).map_err(|error| RadiusError::MalformedIpAddrError { error: error.to_string() })?;
23
24    if parsed_ipv6.len() == 2 {
25        let subnet_number = parsed_ipv6[1].parse::<u16>().map_err(|error| RadiusError::MalformedIpAddrError { error: error.to_string() })?;
26        if subnet_number > 128 {
27            return Err(RadiusError::MalformedIpAddrError{ error: format!("IPv6 Subnet must be no greater than 128, you provided {}", subnet_number) })
28        }
29
30        bytes.append(&mut u16_to_be_bytes(subnet_number).to_vec())
31    }
32    bytes.append(&mut ipv6_address.octets().to_vec());
33    Ok(bytes)
34}
35
36/// Converts **IPv6** bytes into IPv6 string
37pub fn bytes_to_ipv6_string(ipv6: &[u8]) -> Result<String, RadiusError> {
38    match ipv6.len() {
39        18 => {
40            // Case with subnet
41            let subnet_number = u16_from_be_bytes(&ipv6[0..2]);
42            if subnet_number > 128 {
43                return Err(RadiusError::MalformedIpAddrError{ error: format!("IPv6 Subnet must be no greater than 128, but bytes provided {}", subnet_number) })
44            }
45
46            let ipv6_string = Ipv6Addr::new(
47                u16_from_be_bytes(&ipv6[2..4]),
48                u16_from_be_bytes(&ipv6[4..6]),
49                u16_from_be_bytes(&ipv6[6..8]),
50                u16_from_be_bytes(&ipv6[8..10]),
51                u16_from_be_bytes(&ipv6[10..12]),
52                u16_from_be_bytes(&ipv6[12..14]),
53                u16_from_be_bytes(&ipv6[14..16]),
54                u16_from_be_bytes(&ipv6[16..]),
55                ).to_string();
56            Ok(format!("{}/{}",ipv6_string, subnet_number))
57        },
58        16 => {
59            // Case without subnet
60            Ok(Ipv6Addr::new(
61                u16_from_be_bytes(&ipv6[0..2]),
62                u16_from_be_bytes(&ipv6[2..4]),
63                u16_from_be_bytes(&ipv6[4..6]),
64                u16_from_be_bytes(&ipv6[6..8]),
65                u16_from_be_bytes(&ipv6[8..10]),
66                u16_from_be_bytes(&ipv6[10..12]),
67                u16_from_be_bytes(&ipv6[12..14]),
68                u16_from_be_bytes(&ipv6[14..]),
69                ).to_string())
70        },
71        _ => Err(RadiusError::MalformedIpAddrError { error: "Malformed IPv6 bytes".to_string() })
72    }
73}
74
75/// Converts IPv4 Address string into vector of bytes
76///
77/// Should be used for any Attribute of type **ipaddr**, **ipv4addr** or **ipv4prefix** to ensure value is encoded correctly
78pub fn ipv4_string_to_bytes(ipv4: &str) -> Result<Vec<u8>, RadiusError> {
79    let parsed_ipv4: Vec<&str> = ipv4.split('/').collect();
80    let mut bytes: Vec<u8>     = Vec::with_capacity(6);
81    let ipv4_address           = Ipv4Addr::from_str(parsed_ipv4[0]).map_err(|error| RadiusError::MalformedIpAddrError { error: error.to_string() })?;
82
83    if parsed_ipv4.len() == 2 {
84        let subnet_number = parsed_ipv4[1].parse::<u16>().map_err(|error| RadiusError::MalformedIpAddrError { error: error.to_string() })?;
85        if subnet_number > 32 {
86            return Err(RadiusError::MalformedIpAddrError{ error: format!("IPv4 Subnet must be no greater than 32, you provided {}", subnet_number) })
87        }
88
89        bytes.append(&mut u16_to_be_bytes(subnet_number).to_vec())
90    }
91    bytes.append(&mut ipv4_address.octets().to_vec());
92    Ok(bytes)
93}
94
95/// Converts **IPv4** bytes into IPv4 string
96pub fn bytes_to_ipv4_string(ipv4: &[u8]) -> Result<String, RadiusError> {
97    match ipv4.len() {
98        6 => {
99            let subnet_number = u16_from_be_bytes(&ipv4[0..2]);
100            if subnet_number > 32 {
101                return Err(RadiusError::MalformedIpAddrError{ error: format!("IPv4 Subnet must be no greater than 32, but bytes provided {}", subnet_number) })
102            }
103            let ipv4_string: Vec<String> = ipv4.iter().map(|group| group.to_string()).collect();
104            Ok(format!("{}/{}", ipv4_string.join("."), subnet_number))
105
106        },
107        4 => {
108            let ipv4_string: Vec<String> = ipv4.iter().map(|group| group.to_string()).collect();
109            Ok(ipv4_string.join("."))
110        },
111        _ => Err(RadiusError::MalformedIpAddrError { error: "Malformed IPv4 bytes".to_string() })
112    }
113}
114
115
116/// Converts Ifid (Interface Id) string into vector of bytes
117///
118/// Assumes that Interface Id string is in format 0000:0000:0000:0000
119///
120/// Should be used for any Attribute of type **ifid** to ensure value is encoded correctly
121pub fn interfaceid_string_to_bytes(ifid: &str) -> Result<Vec<u8>, RadiusError> {
122    let parsed_ifid: Vec<&str> = ifid.split(':').collect();
123
124    if parsed_ifid.len() % 2 != 0 {
125        return Err(RadiusError::MalformedIfIdError { error: "Length of Interface Id string is not multiple of 2".to_string()})
126    }
127
128    let mut bytes: Vec<u8> = Vec::with_capacity(8);
129    for octets in parsed_ifid {
130        let mut decoded_octets = decode_ifid_octets(&octets)?;
131        bytes.append(&mut decoded_octets);
132    }
133    Ok(bytes)
134}
135
136/// Converts **ifid** bytes into String
137pub fn bytes_to_interfaceid_string(ifid: &[u8]) -> Result<String, RadiusError> {
138    if ifid.len() % 2 != 0 {
139        return Err(RadiusError::MalformedIfIdError { error: "Length of Interface Id bytes is not multiple of 2".to_string()})
140    }
141
142    let mut interfaceid_string: Vec<String> = Vec::new();
143
144    for octets in ifid.chunks_exact(2) {
145        let octets_string = encode_ifid_octets(&octets)?;
146        interfaceid_string.push(octets_string);
147    }
148    Ok(interfaceid_string.join(":"))
149}
150
151fn decode_ifid_octets(octets: &str) -> Result<Vec<u8>, RadiusError> {
152    if octets.len() != 4 {
153        Err(RadiusError::MalformedIfIdError { error: "Interface Id should have octets of 4, ie 0000".to_string()})
154    } else {
155        (0..octets.len())
156            .step_by(2)
157            .map(|index| u8::from_str_radix(&octets[index..index + 2], 16).map_err(|error| RadiusError::MalformedIfIdError { error: error.to_string() }))
158            .collect()
159    }
160}
161
162fn encode_ifid_octets(octets: &[u8]) -> Result<String, RadiusError>  {
163    if octets.len() != 2 {
164        Err(RadiusError::MalformedIfIdError { error: "There should be 2 octets".to_string()})
165    } else {
166        let mut string_octet = String::with_capacity(4);
167        for b in octets {
168            write!(string_octet, "{:02x}", b).map_err(|error| RadiusError::MalformedIfIdError { error: error.to_string() })?;
169        }
170        Ok(string_octet)
171    }
172}
173
174/// Converts u32 into vector of bytes
175///
176/// Should be used for any Attribute of type **integer** to ensure value is encoded correctly
177pub fn integer_to_bytes(integer: u32) -> Vec<u8> {
178    integer.to_be_bytes().to_vec()
179}
180
181/// Converts **integer** bytes into u32
182pub fn bytes_to_integer(integer: &[u8; 4]) -> u32 {
183    u32::from_be_bytes(*integer)
184}
185
186/// Converts u64 into vector of bytes
187///
188/// Should be used for any Attribute of type **integer64** to ensure value is encoded correctly
189pub fn integer64_to_bytes(integer: u64) -> Vec<u8> {
190    integer.to_be_bytes().to_vec()
191}
192
193/// Converts **integer64** bytes into u64
194pub fn bytes_to_integer64(integer: &[u8; 8]) -> u64 {
195    u64::from_be_bytes(*integer)
196}
197
198/// Converts timestamp (u32) into vector of bytes
199///
200/// Should be used for any Attribute of type **date** to ensure value is encoded correctly
201pub fn timestamp_to_bytes(timestamp: u32) -> Vec<u8> {
202    timestamp.to_be_bytes().to_vec()
203}
204
205/// Converts **date** bytes into u32 (timestamp)
206pub fn bytes_to_timestamp(timestamp: &[u8; 4]) -> u32 {
207    u32::from_be_bytes(*timestamp)
208}
209
210/// Encrypts data since RADIUS packet is sent in plain text
211///
212/// Should be used to encrypt value of **User-Password** attribute (but could also be used to
213/// encrypt any data)
214pub fn encrypt_data(data: &[u8], authenticator: &[u8], secret: &[u8]) -> Vec<u8> {
215    /* Step 1. Ensure that data buffer's length is multiple of 16
216    *  Step 2. Construct hash:
217    *
218    *  On each iteration:
219    *   1. read 16 elements from data
220    *   2. calculate MD5 hash for: provided secret + (authenticator(on 1st iteration) or 16 elements of result from previous iteration (2nd+ iteration))
221    *   3. execute bitwise XOR between each of 16 elements of MD5 hash and data buffer and record it in results vector
222    *
223    * Step 3. Return result vector
224    */
225    let mut hash = [0u8; 16];
226    let padding  = 16 - data.len() % 16;
227
228
229    let mut result = Vec::with_capacity(data.len() + padding);
230    result.extend_from_slice(data);
231    result.extend_from_slice(&hash[..padding]);
232
233    encrypt_helper(&mut result, authenticator, &mut hash, secret);
234    result
235}
236
237/// Decrypts data since RADIUS packet is sent in plain text
238///
239/// Should be used to decrypt value of **User-Password** attribute (but could also be used to
240/// decrypt any data)
241pub fn decrypt_data(data: &[u8], authenticator: &[u8], secret: &[u8]) -> Vec<u8> {
242    /*
243     * To decrypt the data, we need to apply the same algorithm as in encrypt_data()
244     * but with small change
245     *
246     *  On each iteration:
247     *   1. read 16 elements from data
248     *   2. calculate MD5 hash for: provided secret + (authenticator(on 1st iteration) or 16 elements of data buffer from previous iteration (2nd+ iteration))
249     *   3. execute bitwise XOR between each of 16 elements of MD5 hash and data buffer and record it in results vector
250     *
251     */
252    if data.len() <= 15 {
253        return Vec::new()
254    }
255
256    let mut result  = Vec::with_capacity(data.len());
257    let prev_result = authenticator;
258
259    decrypt_helper(data, prev_result, &mut result, secret);
260
261    while result[result.len()-1] == 0 {
262        result.pop();
263    }
264
265    result
266}
267
268/// Encrypts data with salt since RADIUS packet is sent in plain text
269///
270/// Should be used for RADIUS Tunnel-Password Attribute
271pub fn salt_encrypt_data(data: &[u8], authenticator: &[u8], salt: &[u8], secret: &[u8]) -> Vec<u8> {
272    if data.is_empty() {
273        return Vec::new();
274    }
275
276    let mut hash   = [0u8; 16];
277    let padding    = 15 - data.len() % 16;
278    let mut result = Vec::with_capacity(data.len() + 3 + padding); // make buffer big enough to fit the salt & encrypted data
279
280    result.extend_from_slice(salt);
281    result.push(data.len() as u8);
282    result.extend_from_slice(data);
283    result.extend_from_slice(&hash[..padding]);
284
285    let salted_authenticator = &mut [0u8; 18];
286    salted_authenticator[..16].copy_from_slice(authenticator);
287    salted_authenticator[16..].copy_from_slice(salt);
288
289    let prev_result = &salted_authenticator[..];
290    let current     = &mut result[2..];
291
292    encrypt_helper(current, prev_result, &mut hash, secret);
293    result
294}
295
296/// Decrypts data with salt since RADIUS packet is sent in plain text
297///
298/// Should be used for RADIUS Tunnel-Password Attribute
299pub fn salt_decrypt_data(data: &[u8], authenticator: &[u8], secret: &[u8]) -> Result<Vec<u8>, RadiusError> {
300    /*
301     * The salt decryption behaves almost the same as normal Password encryption in RADIUS
302     * The main difference is the presence of a two byte salt, which is appended to the authenticator
303     */
304    if data.len() <= 1 {
305        return Err(RadiusError::MalformedAttributeError {error: "salt encrypted attribute too short".to_string()});
306    }
307    if data.len() <= 17 {
308        // If len() equals to 3, it means that there is a Salt or there is a salt & data.len(): Both cases mean "Password is empty"
309        // But for this function to actually work len() must be at least 18, otherwise we cannot
310        // decrypt data as it is invalid
311        return Ok(Vec::new());
312    }
313
314    let salted_authenticator = &mut [0u8; 18];
315    salted_authenticator[..16].copy_from_slice(authenticator);
316    salted_authenticator[16..].copy_from_slice(&data[..2]);
317
318    let mut result      = Vec::with_capacity(data.len()-2);
319    let prev_result = &salted_authenticator[..];
320
321    decrypt_helper(&data[2..], prev_result, &mut result, secret);
322
323    let target_len = usize::from(result.remove(0));
324
325    if target_len > data.len() - 3 {
326        return Err(RadiusError::MalformedAttributeError { error: "Tunnel Password is too long (shared secret might be wrong)".to_string()});
327    }
328
329    result.truncate(target_len);
330    Ok(result)
331}
332
333// -----------------------------------------
334fn encrypt_helper<'a:'b, 'b>(mut out: &'a mut [u8], mut result: &'b [u8], hash: &mut[u8], secret: &[u8]) {
335    loop {
336        let mut md5 = Md5::new();
337        md5.update(secret);
338        md5.update(result);
339        hash.copy_from_slice(&md5.finalize());
340
341        for (_data, _hash) in out.iter_mut().zip(hash.iter()) {
342            *_data ^= _hash
343        }
344
345        let (_prev, _current) = out.split_at_mut(16);
346        result = _prev;
347        out   = _current;
348
349        if out.is_empty() { break }
350    }
351}
352
353fn decrypt_helper<'a:'b, 'b>(data: &'a [u8], mut prev_result: &'b [u8], result: &mut Vec<u8>, secret: &[u8]) {
354    let mut hash = [0u8; 16];
355
356    for data_chunk in data.chunks_exact(16) {
357        let mut md5 = Md5::new();
358        md5.update(secret);
359        md5.update(prev_result);
360        hash.copy_from_slice(&md5.finalize());
361
362        for (_data, _hash) in data_chunk.iter().zip(hash.iter_mut()) {
363            *_hash ^= _data;
364        }
365
366        result.extend_from_slice(&hash);
367        prev_result = data_chunk;
368    }
369}
370
371fn u16_to_be_bytes(u16_data: u16) -> [u8;2] {
372    u16_data.to_be_bytes()
373}
374
375pub(crate) fn u16_from_be_bytes(bytes: &[u8]) -> u16 {
376    u16::from_be_bytes(bytes.try_into().expect("slice with incorrect length"))
377}
378// -----------------------------------------
379
380
381#[cfg(test)]
382mod tests {
383    use super::*;
384
385    #[test]
386    fn test_ipv6_to_bytes_wo_subnet() {
387        let ipv6_bytes = ipv6_string_to_bytes("fc66::1").unwrap();
388        assert_eq!(ipv6_bytes, vec![252, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
389    }
390    #[test]
391    fn test_bytes_to_ipv6_string_wo_subnet() {
392        let expected_ipv6_string = "fc66::1";
393        let ipv6_bytes           = vec![252, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
394
395        assert_eq!(expected_ipv6_string, bytes_to_ipv6_string(&ipv6_bytes).unwrap());
396    }
397
398    #[test]
399    fn test_ipv6_to_bytes_w_subnet() {
400        let ipv6_bytes = ipv6_string_to_bytes("fc66::1/64").unwrap();
401        assert_eq!(ipv6_bytes, [0, 64, 252, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
402    }
403    #[test]
404    fn test_bytes_to_ipv6_string_w_subnet() {
405        let expected_ipv6_string = "fc66::1/64";
406        let ipv6_bytes           = vec![0, 64, 252, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
407
408        assert_eq!(expected_ipv6_string, bytes_to_ipv6_string(&ipv6_bytes).unwrap());
409    }
410    #[test]
411    fn test_invalid_ipv6_string_to_bytes() {
412        assert!(ipv6_string_to_bytes("::/:").is_err())
413    }
414    #[test]
415    fn test_empty_ipv6_string_to_bytes() {
416        assert!(ipv6_string_to_bytes("").is_err())
417    }
418
419    #[test]
420    fn test_ipv4_string_to_bytes() {
421        let ipv4_bytes = ipv4_string_to_bytes("192.1.10.1").unwrap();
422
423        assert_eq!(ipv4_bytes, [192, 1, 10, 1]);
424    }
425    #[test]
426    fn test_empty_ipv4_string_to_bytes() {
427        assert!(ipv4_string_to_bytes("").is_err())
428    }
429
430    #[test]
431    fn test_ipv4_bytes_to_string() {
432        let ipv4_bytes = vec![192, 1, 10, 1];
433        let ipv4_string = bytes_to_ipv4_string(&ipv4_bytes).unwrap();
434
435        assert_eq!(ipv4_string, "192.1.10.1".to_string());
436    }
437
438    #[test]
439    fn test_interfaceid_string_to_bytes() {
440        let ifid_bytes = interfaceid_string_to_bytes("fc66:1111:2222:3333").unwrap();
441        assert_eq!(ifid_bytes, vec![252, 102, 17, 17, 34, 34, 51, 51]);
442    }
443    #[test]
444    fn test_interfaceid_string_to_bytes_invalid() {
445        match interfaceid_string_to_bytes("fc66:1111:3333") {
446            Ok(_)    => assert!(false),
447            Err(err) => assert_eq!(err.to_string(), String::from("Provided Interface Id is malformed: Length of Interface Id string is not multiple of 2"))
448        }
449    }
450
451    #[test]
452    fn test_bytes_to_interfaceid_string() {
453        let expected_ifid = "fc66:1111:2222:3333";
454        let ifid_bytes    = vec![252, 102, 17, 17, 34, 34, 51, 51];
455
456        let ifid_string = bytes_to_interfaceid_string(&ifid_bytes).unwrap();
457        assert_eq!(expected_ifid, ifid_string)
458    }
459    #[test]
460    fn test_bytes_to_interfaceid_string_invalid() {
461        let ifid_bytes    = vec![252, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
462
463        match bytes_to_interfaceid_string(&ifid_bytes) {
464            Ok(_)    => assert!(false),
465            Err(err) => assert_eq!(err.to_string(), String::from("Provided Interface Id is malformed: Length of Interface Id bytes is not multiple of 2"))
466        }
467    }
468
469    #[test]
470    fn test_encrypt_empty_data() {
471        let secret        = String::from("secret");
472        let authenticator = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
473
474        let encrypted_bytes = encrypt_data("".as_bytes(), &authenticator, &secret.as_bytes());
475
476        assert_eq!(encrypted_bytes, vec![247, 21, 232, 156, 149, 54, 40, 185, 62, 29, 218, 130, 102, 174, 191, 250]);
477    }
478
479    #[test]
480    fn test_encrypt_small_data() {
481        let secret        = String::from("secret");
482        let authenticator = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
483
484        let encrypted_bytes = encrypt_data("p".as_bytes(), &authenticator, &secret.as_bytes());
485
486        assert_eq!(encrypted_bytes, vec![135, 21, 232, 156, 149, 54, 40, 185, 62, 29, 218, 130, 102, 174, 191, 250]);
487    }
488
489    #[test]
490    fn test_encrypt_normal_data() {
491        let secret        = String::from("secret");
492        let authenticator = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
493
494        let encrypted_bytes = encrypt_data("password".as_bytes(), &authenticator, &secret.as_bytes());
495
496        assert_eq!(encrypted_bytes, vec![135, 116, 155, 239, 226, 89, 90, 221, 62, 29, 218, 130, 102, 174, 191, 250]);
497    }
498
499    #[test]
500    fn test_encrypt_long_data() {
501        let secret        = String::from("secret");
502        let authenticator = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
503
504        let encrypted_bytes = encrypt_data("a very long password, which will need multiple iterations".as_bytes(), &authenticator, &secret.as_bytes());
505        assert_eq!(encrypted_bytes, vec![150, 53, 158, 249, 231, 79, 8, 213, 81, 115, 189, 162, 22, 207, 204, 137, 193,
506                   149, 82, 147, 72, 149, 79, 48, 187, 199, 194, 200, 246, 6, 186, 182, 220, 19, 227, 32, 26, 20, 9, 152,
507                   63, 40, 41, 91, 212, 22, 158, 54, 91, 247, 151, 67, 250,170, 105, 94, 20, 105, 120, 196, 237, 191, 99, 69]
508        );
509    }
510
511    #[test]
512    fn test_encrypt_limit_long_data() {
513        let secret        = String::from("secret");
514        let authenticator = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
515        let data          = "a very long password, which will need multiple iterations. a very long password, which will need multiple iterations. a very long password, which will need multiple iterations. a very long password, which will need multiple iterations. a very long passw";
516
517        let encrypted_bytes = encrypt_data(data.as_bytes(), &authenticator, &secret.as_bytes());
518        assert_eq!(encrypted_bytes, vec![150, 53, 158, 249, 231, 79, 8, 213, 81, 115, 189, 162, 22, 207, 204, 137, 193, 149, 82, 147, 72, 149, 79, 48, 187, 199, 194, 200,
519                                         246, 6, 186, 182, 220, 19, 227, 32, 26, 20, 9, 152, 63, 40, 41, 91, 212, 22, 158, 54, 91, 247, 151, 67, 250, 170, 105, 94, 20, 71,
520                                         88, 165, 205, 201, 6, 55, 222, 205, 192, 227, 172, 93, 166, 15, 33, 86, 56, 181, 52, 4, 49, 190, 186, 17, 125, 50, 140, 52, 130, 194,
521                                         125, 93, 177, 65, 217, 195, 23, 75, 175, 219, 244, 156, 133, 145, 20, 176, 36, 90, 16, 77, 148, 221, 251, 155, 9, 107, 213, 140, 107,
522                                         112, 161, 99, 6, 108, 106, 33, 69, 192, 191, 98, 30, 147, 197, 72, 160, 234, 50, 243, 195, 62, 72, 225, 19, 63, 28, 221, 164, 43, 67,
523                                         63, 206, 208, 124, 254, 202, 118, 229, 58, 180, 210, 100, 149, 120, 97, 23, 203, 197, 139, 244, 241, 175, 232, 149, 77, 43, 231, 27, 56,
524                                         250, 58, 251, 6, 203, 197, 190, 78, 83, 127, 164, 31, 211, 52, 74, 92, 36, 250, 236, 210, 72, 52, 55, 248, 161, 160, 95, 102, 63, 190, 43,
525                                         253, 224, 114, 62, 23, 11, 242, 186, 91, 132, 14, 76, 171, 26, 1, 51, 78, 144, 50, 228, 212, 47, 104, 98, 60, 245, 1, 103, 217, 49, 105,
526                                         38, 108, 93, 85, 224, 227, 33, 50, 144, 0, 233, 54, 174, 67, 174, 101, 189, 41]);
527    }
528
529    #[test]
530    fn test_decrypt_under16_data() {
531        let secret         = String::from("secret");
532        let authenticator  = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
533
534        let expected_data  = String::from("");
535        let encrypted_data = vec![135, 116, 155, 239, 226, 89, 90, 221, 62, 29, 218, 130, 102, 174, 191];
536
537        let decrypted_data = decrypt_data(&encrypted_data, &authenticator, &secret.as_bytes());
538
539        assert_eq!(expected_data.as_bytes().to_vec(), decrypted_data);
540    }
541
542    #[test]
543    fn test_decrypt_normal_data() {
544        let secret         = String::from("secret");
545        let authenticator  = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
546
547        let expected_data  = String::from("password");
548        let encrypted_data = vec![135, 116, 155, 239, 226, 89, 90, 221, 62, 29, 218, 130, 102, 174, 191, 250];
549
550        let decrypted_data = decrypt_data(&encrypted_data, &authenticator, &secret.as_bytes());
551
552        assert_eq!(expected_data.as_bytes().to_vec(), decrypted_data);
553    }
554
555    #[test]
556    fn test_descrypt_long_data() {
557        let secret         = String::from("secret");
558        let authenticator  = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
559
560        let expected_data  = String::from("a very long password, which will need multiple iterations");
561        let encrypted_data = vec![150, 53, 158, 249, 231, 79, 8, 213, 81, 115, 189, 162, 22, 207, 204, 137, 193,
562        149, 82, 147, 72, 149, 79, 48, 187, 199, 194, 200, 246, 6, 186, 182, 220, 19, 227, 32, 26, 20, 9, 152, 63,
563        40, 41, 91, 212, 22, 158, 54, 91, 247, 151, 67, 250,170, 105, 94, 20, 105, 120, 196, 237, 191, 99, 69];
564
565        let decrypted_data = decrypt_data(&encrypted_data, &authenticator, &secret.as_bytes());
566        assert_eq!(expected_data.as_bytes().to_vec(), decrypted_data);
567    }
568
569    #[test]
570    fn test_descrypt_limit_long_data() {
571        let secret         = String::from("secret");
572        let authenticator  = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
573
574        let expected_data  = String::from("a very long password, which will need multiple iterations. a very long password, which will need multiple iterations. a very long password, which will need multiple iterations. a very long password, which will need multiple iterations. a very long passw");
575        let encrypted_data = vec![150, 53, 158, 249, 231, 79, 8, 213, 81, 115, 189, 162, 22, 207, 204, 137, 193, 149, 82, 147, 72, 149, 79, 48, 187, 199, 194, 200,
576                                  246, 6, 186, 182, 220, 19, 227, 32, 26, 20, 9, 152, 63, 40, 41, 91, 212, 22, 158, 54, 91, 247, 151, 67, 250, 170, 105, 94, 20, 71,
577                                  88, 165, 205, 201, 6, 55, 222, 205, 192, 227, 172, 93, 166, 15, 33, 86, 56, 181, 52, 4, 49, 190, 186, 17, 125, 50, 140, 52, 130, 194,
578                                  125, 93, 177, 65, 217, 195, 23, 75, 175, 219, 244, 156, 133, 145, 20, 176, 36, 90, 16, 77, 148, 221, 251, 155, 9, 107, 213, 140, 107,
579                                  112, 161, 99, 6, 108, 106, 33, 69, 192, 191, 98, 30, 147, 197, 72, 160, 234, 50, 243, 195, 62, 72, 225, 19, 63, 28, 221, 164, 43, 67,
580                                  63, 206, 208, 124, 254, 202, 118, 229, 58, 180, 210, 100, 149, 120, 97, 23, 203, 197, 139, 244, 241, 175, 232, 149, 77, 43, 231, 27, 56,
581                                  250, 58, 251, 6, 203, 197, 190, 78, 83, 127, 164, 31, 211, 52, 74, 92, 36, 250, 236, 210, 72, 52, 55, 248, 161, 160, 95, 102, 63, 190, 43,
582                                  253, 224, 114, 62, 23, 11, 242, 186, 91, 132, 14, 76, 171, 26, 1, 51, 78, 144, 50, 228, 212, 47, 104, 98, 60, 245, 1, 103, 217, 49, 105,
583                                  38, 108, 93, 85, 224, 227, 33, 50, 144, 0, 233, 54, 174, 67, 174, 101, 189, 41];
584
585        let decrypted_data = decrypt_data(&encrypted_data, &authenticator, &secret.as_bytes());
586        assert_eq!(expected_data.as_bytes().to_vec(), decrypted_data);
587    }
588
589    #[test]
590    fn test_salt_encrypt_normal_data() {
591        let secret               = b"secret";
592        let authenticator: &[u8] = &[0u8; 16];
593
594        let plaintext             = b"password";
595        let encrypted_data: &[u8] = &[0x85, 0x9a, 0xe3, 0x88, 0x34, 0x49, 0xf2, 0x1e, 0x14, 0x4c, 0x76, 0xc8, 0xb2, 0x1a, 0x1d, 0x4f, 0x0c, 0xdc];
596        let salt                  = &encrypted_data[..2];
597
598        assert_eq!(encrypted_data, salt_encrypt_data(plaintext, authenticator, salt, secret).as_slice());
599    }
600
601    #[test]
602    fn test_salt_encrypt_long_data() {
603        let secret               = b"secret";
604        let authenticator: &[u8] = &[0u8; 16];
605
606        let plaintext_long             = b"a very long password, which will need multiple iterations";
607        let encrypted_data_long: &[u8] = &[0x85, 0xd9, 0x61, 0x72, 0x75, 0x37, 0xcf, 0x15, 0x20,
608        0x19, 0x3b, 0x38, 0x39, 0x0e, 0x42, 0x21, 0x9b, 0x5e, 0xcb, 0x93, 0x25, 0x7d, 0xb4, 0x07,
609        0x0c, 0xc1, 0x52, 0xcf, 0x38, 0x76, 0x29, 0x02, 0xc7, 0xb1, 0x29, 0xdf, 0x63, 0x96, 0x26,
610        0x1a, 0x27, 0xe5, 0xc3, 0x13, 0x78, 0xa7, 0x97, 0xd8, 0x97, 0x9a, 0x45, 0xc3, 0x70, 0xd3,
611        0xe4, 0xe2, 0xae, 0xd0, 0x55, 0x77, 0x19, 0xa5, 0xb6, 0x44, 0xe6, 0x8a];
612        let salt                       = &encrypted_data_long[..2];
613
614        assert_eq!(encrypted_data_long, salt_encrypt_data(plaintext_long, authenticator, salt, secret).as_slice());
615    }
616
617    #[test]
618    fn test_salt_decrypt_data() {
619        let secret               = b"secret";
620        let authenticator: &[u8] = &[0u8; 16];
621
622        let plaintext: &[u8]      = b"password";
623        let encrypted_data: &[u8] = &[0x85, 0x9a, 0xe3, 0x88, 0x34, 0x49, 0xf2, 0x1e, 0x14, 0x4c, 0x76, 0xc8, 0xb2, 0x1a, 0x1d, 0x4f, 0x0c, 0xdc];
624
625        assert_eq!(plaintext, salt_decrypt_data(encrypted_data, authenticator, secret).unwrap().as_slice());
626    }
627
628    #[test]
629    fn test_salt_decrypt_long_data() {
630        let secret               = b"secret";
631        let authenticator: &[u8] = &[0u8; 16];
632
633        let plaintext_long             = b"a very long password, which will need multiple iterations";
634        let encrypted_data_long: &[u8] = &[0x85, 0xd9, 0x61, 0x72, 0x75, 0x37, 0xcf, 0x15, 0x20,
635        0x19, 0x3b, 0x38, 0x39, 0x0e, 0x42, 0x21, 0x9b, 0x5e, 0xcb, 0x93, 0x25, 0x7d, 0xb4, 0x07,
636        0x0c, 0xc1, 0x52, 0xcf, 0x38, 0x76, 0x29, 0x02, 0xc7, 0xb1, 0x29, 0xdf, 0x63, 0x96, 0x26,
637        0x1a, 0x27, 0xe5, 0xc3, 0x13, 0x78, 0xa7, 0x97, 0xd8, 0x97, 0x9a, 0x45, 0xc3, 0x70, 0xd3,
638        0xe4, 0xe2, 0xae, 0xd0, 0x55, 0x77, 0x19, 0xa5, 0xb6, 0x44, 0xe6, 0x8a];
639
640        assert_eq!(plaintext_long.to_vec(), salt_decrypt_data(encrypted_data_long, authenticator, secret).unwrap());
641    }
642
643    #[test]
644    fn test_integer_to_bytes() {
645        let integer: u32 = 10000;
646
647        assert_eq!(vec![0, 0, 39, 16], integer_to_bytes(integer));
648    }
649
650    #[test]
651    fn test_bytes_to_integer() {
652        let integer_bytes = [0, 0, 39, 16];
653
654        assert_eq!(10000, bytes_to_integer(&integer_bytes));
655    }
656
657    #[test]
658    fn test_timestamp_to_bytes() {
659        let timestamp: u32 = 1598523933;
660
661        assert_eq!(vec![95, 71, 138, 29], timestamp_to_bytes(timestamp));
662    }
663
664    #[test]
665    fn test_bytes_to_timestamp() {
666        let timestamp_bytes = [95, 71, 138, 29];
667
668        assert_eq!(1598523933, bytes_to_timestamp(&timestamp_bytes));
669    }
670}