-
Notifications
You must be signed in to change notification settings - Fork 464
/
sys.rs
61 lines (47 loc) · 3.14 KB
/
sys.rs
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
55
56
57
58
59
60
61
use windows_sys::{core::*, Win32::Foundation::*, Win32::Security::Cryptography::*};
#[test]
fn test() {
unsafe {
let mut rng = 0;
// TODO: workaround for https://github.com/microsoft/win32metadata/issues/1008
assert_eq!(STATUS_SUCCESS, BCryptOpenAlgorithmProvider(&mut rng, w!("RNG"), std::ptr::null(), 0));
let mut des = 0;
assert_eq!(STATUS_SUCCESS, BCryptOpenAlgorithmProvider(&mut des, w!("3DES"), std::ptr::null(), 0));
let mut object_len = [0; 4];
let mut bytes_copied = 0;
assert_eq!(STATUS_SUCCESS, BCryptGetProperty(des, w!("ObjectLength"), object_len.as_mut_ptr(), object_len.len() as _, &mut bytes_copied, 0));
let object_len = u32::from_le_bytes(object_len);
let mut shared_secret = vec![0; object_len as _];
assert_eq!(STATUS_SUCCESS, BCryptGenRandom(rng, shared_secret.as_mut_ptr(), shared_secret.len() as _, 0));
let mut encrypt_key = 0;
assert_eq!(STATUS_SUCCESS, BCryptGenerateSymmetricKey(des, &mut encrypt_key, std::ptr::null_mut(), 0, shared_secret.as_ptr(), shared_secret.len() as _, 0));
let mut block_len = [0; 4];
assert_eq!(STATUS_SUCCESS, BCryptGetProperty(des, w!("BlockLength"), block_len.as_mut_ptr(), block_len.len() as _, &mut bytes_copied, 0));
let block_len = u32::from_le_bytes(block_len) as usize;
let send_message = "I ❤️ Rust";
let mut send_buffer = vec![0; block_len * ((send_message.len() + (block_len - 1)) / block_len)];
send_buffer[..send_message.len()].copy_from_slice(send_message.as_bytes());
let mut encrypted_len = 0;
assert_eq!(STATUS_SUCCESS, BCryptEncrypt(encrypt_key, send_buffer.as_ptr(), send_buffer.len() as _, std::ptr::null(), std::ptr::null_mut(), 0, std::ptr::null_mut(), 0, &mut encrypted_len, 0));
let mut encrypted = vec![0; encrypted_len as _];
assert_eq!(STATUS_SUCCESS, BCryptEncrypt(encrypt_key, send_buffer.as_ptr(), send_buffer.len() as _, std::ptr::null(), std::ptr::null_mut(), 0, encrypted.as_mut_ptr(), encrypted.len() as _, &mut encrypted_len, 0));
let mut decrypt_key = 0;
assert_eq!(STATUS_SUCCESS, BCryptGenerateSymmetricKey(des, &mut decrypt_key, std::ptr::null_mut(), 0, shared_secret.as_ptr(), shared_secret.len() as _, 0));
let mut decrypted_len = 0;
assert_eq!(STATUS_SUCCESS, BCryptDecrypt(decrypt_key, encrypted.as_ptr(), encrypted.len() as _, std::ptr::null(), std::ptr::null_mut(), 0, std::ptr::null_mut(), 0, &mut decrypted_len, 0));
let mut decrypted = vec![0; decrypted_len as _];
assert_eq!(STATUS_SUCCESS, BCryptDecrypt(decrypt_key, encrypted.as_ptr(), encrypted.len() as _, std::ptr::null(), std::ptr::null_mut(), 0, decrypted.as_mut_ptr(), decrypted.len() as _, &mut decrypted_len, 0));
let receive_message = std::str::from_utf8(trim_null_end(&decrypted)).expect("Not a valid message");
assert_eq!(send_message, receive_message);
}
}
pub const fn trim_null_end(mut bytes: &[u8]) -> &[u8] {
while let [rest @ .., last] = bytes {
if *last == 0 {
bytes = rest;
} else {
break;
}
}
bytes
}