From 3ddbae0b3a7943f1352609d124f2a672d2f2c28e Mon Sep 17 00:00:00 2001 From: WingZer0o Date: Mon, 13 May 2024 23:33:55 -0400 Subject: [PATCH 1/3] generate AES nonce at rust level --- src/aes.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/aes.rs b/src/aes.rs index 0d83d1a..2ce419c 100644 --- a/src/aes.rs +++ b/src/aes.rs @@ -2,12 +2,18 @@ use aes_gcm::{ aead::{generic_array::GenericArray, AeadMut, OsRng}, Aes128Gcm, Aes256Gcm, Key, KeyInit, Nonce, }; +use rand::RngCore; use rand_07::AsByteSliceMut; use std::ffi::{c_char, c_uchar, CStr, CString}; -use x25519_dalek::x25519; use crate::x25519; +#[repr(C)] +pub struct AesNonce { + pub nonce: *mut c_uchar, + pub length: usize +} + #[repr(C)] pub struct AesBytesEncrypt { pub ciphertext: *mut c_uchar, @@ -190,6 +196,22 @@ pub fn aes_128_key_and_nonce_from_x25519_diffie_hellman_shared_secret_test() { assert_eq!(password_cstr, plain_text_result_slice); } +#[no_mangle] +pub extern "C" fn aes_nonce() -> AesNonce { + let mut rng = &mut OsRng; + let mut random_bytes = Vec::with_capacity(12); + random_bytes.resize(12, 0); + rng.fill_bytes(&mut random_bytes); + let capacity = random_bytes.capacity(); + random_bytes.reserve_exact(capacity); + let result = AesNonce { + nonce: random_bytes.as_mut_ptr(), + length: random_bytes.len() + }; + std::mem::forget(random_bytes); + result +} + #[no_mangle] pub extern "C" fn aes_256_key() -> *mut c_char { return CString::new(base64::encode(Aes256Gcm::generate_key(&mut OsRng))) From acd824af27d0fef7d3d0cf89dbea1ae897fb33ce Mon Sep 17 00:00:00 2001 From: WingZer0o Date: Mon, 13 May 2024 23:53:53 -0400 Subject: [PATCH 2/3] aes nonce encrypting and decrypting with byte[] --- src/aes.rs | 56 ++++++++++++++++-------------------------------------- 1 file changed, 16 insertions(+), 40 deletions(-) diff --git a/src/aes.rs b/src/aes.rs index 2ce419c..db5a6a4 100644 --- a/src/aes.rs +++ b/src/aes.rs @@ -228,19 +228,13 @@ pub extern "C" fn aes_128_key() -> *mut c_char { #[no_mangle] pub extern "C" fn aes_128_encrypt_bytes_with_key( - nonce_key: *const c_char, + nonce_key: *const c_uchar, + nonce_key_length: usize, key: *const c_char, to_encrypt: *const c_uchar, to_encrypt_length: usize, ) -> AesBytesEncrypt { - let nonce_string_key = unsafe { - assert!(!nonce_key.is_null()); - CStr::from_ptr(nonce_key) - } - .to_str() - .unwrap() - .as_bytes(); - + let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }; let key_string = unsafe { assert!(!key.is_null()); CStr::from_ptr(key) @@ -252,7 +246,7 @@ pub extern "C" fn aes_128_encrypt_bytes_with_key( let mut decoded_string_key = base64::decode(key_string).unwrap(); let key = GenericArray::from_slice(decoded_string_key.as_byte_slice_mut()); let mut cipher = Aes128Gcm::new(&key); - let nonce = Nonce::from_slice(nonce_string_key); // 96-bits; unique per message + let nonce = Nonce::from_slice(nonce_slice); // 96-bits; unique per message let mut ciphertext: Vec = cipher.encrypt(nonce, to_encrypt_slice.as_ref()).unwrap(); let capacity = ciphertext.capacity(); ciphertext.reserve_exact(capacity); @@ -266,19 +260,13 @@ pub extern "C" fn aes_128_encrypt_bytes_with_key( #[no_mangle] pub extern "C" fn aes_256_encrypt_bytes_with_key( - nonce_key: *const c_char, + nonce_key: *const c_uchar, + nonce_key_length: usize, key: *const c_char, to_decrypt: *const c_uchar, to_decrypt_length: usize, ) -> AesBytesEncrypt { - let nonce_string_key = unsafe { - assert!(!nonce_key.is_null()); - CStr::from_ptr(nonce_key) - } - .to_str() - .unwrap() - .as_bytes(); - + let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }; let key_string = unsafe { assert!(!key.is_null()); CStr::from_ptr(key) @@ -289,7 +277,7 @@ pub extern "C" fn aes_256_encrypt_bytes_with_key( let mut decoded_string_key = base64::decode(key_string).unwrap(); let key = GenericArray::from_slice(decoded_string_key.as_byte_slice_mut()); let mut cipher = Aes256Gcm::new(&key); - let nonce = Nonce::from_slice(nonce_string_key); // 96-bits; unique per message + let nonce = Nonce::from_slice(nonce_slice); // 96-bits; unique per message let mut ciphertext = cipher.encrypt(nonce, to_decrypt_slice).unwrap(); let capacity = ciphertext.capacity(); ciphertext.reserve_exact(capacity); @@ -303,19 +291,13 @@ pub extern "C" fn aes_256_encrypt_bytes_with_key( #[no_mangle] pub extern "C" fn aes_128_decrypt_bytes_with_key( - nonce_key: *const c_char, + nonce_key: *const c_uchar, + nonce_key_length: usize, key: *const c_char, to_decrypt: *const c_uchar, to_decrypt_length: usize, ) -> AesBytesDecrypt { - let nonce_string_key = unsafe { - assert!(!nonce_key.is_null()); - CStr::from_ptr(nonce_key) - } - .to_str() - .unwrap() - .as_bytes(); - + let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }; let key_string = unsafe { assert!(!key.is_null()); CStr::from_ptr(key) @@ -326,7 +308,7 @@ pub extern "C" fn aes_128_decrypt_bytes_with_key( let mut decoded_string_key = base64::decode(key_string).unwrap(); let key = GenericArray::from_slice(decoded_string_key.as_byte_slice_mut()); let mut cipher = Aes128Gcm::new(&key); - let nonce = Nonce::from_slice(nonce_string_key); // 96-bits; unique per message + let nonce = Nonce::from_slice(nonce_slice); // 96-bits; unique per message let mut plaintext = cipher.decrypt(nonce, to_decrypt_slice).unwrap(); let capacity = plaintext.capacity(); plaintext.reserve_exact(capacity); @@ -340,19 +322,13 @@ pub extern "C" fn aes_128_decrypt_bytes_with_key( #[no_mangle] pub extern "C" fn aes_256_decrypt_bytes_with_key( - nonce_key: *const c_char, + nonce_key: *const c_uchar, + nonce_key_length: usize, key: *const c_char, to_decrypt: *const c_uchar, to_decrypt_length: usize, ) -> AesBytesDecrypt { - let nonce_string_key = unsafe { - assert!(!nonce_key.is_null()); - CStr::from_ptr(nonce_key) - } - .to_str() - .unwrap() - .as_bytes(); - + let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }; let key_string = unsafe { assert!(!key.is_null()); CStr::from_ptr(key) @@ -363,7 +339,7 @@ pub extern "C" fn aes_256_decrypt_bytes_with_key( let mut decoded_string_key = base64::decode(key_string).unwrap(); let key = GenericArray::from_slice(decoded_string_key.as_byte_slice_mut()); let mut cipher = Aes256Gcm::new(&key); - let nonce = Nonce::from_slice(nonce_string_key); // 96-bits; unique per message + let nonce = Nonce::from_slice(nonce_slice); // 96-bits; unique per message let mut plaintext = cipher.decrypt(nonce, to_decrypt_slice).unwrap(); let capacity = plaintext.capacity(); plaintext.reserve_exact(capacity); From d0a85b59477e8f31f0e9e3a3cdf33c3db931aac0 Mon Sep 17 00:00:00 2001 From: WingZer0o Date: Tue, 14 May 2024 20:10:04 -0400 Subject: [PATCH 3/3] adjusting aes nonce for x25519 diffie hellman aes encrypt and decrypt --- src/aes.rs | 52 +++++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/src/aes.rs b/src/aes.rs index db5a6a4..1760da3 100644 --- a/src/aes.rs +++ b/src/aes.rs @@ -29,7 +29,8 @@ pub struct AesBytesDecrypt { #[repr(C)] pub struct AesNonceAndKeyFromX25519DiffieHellman { pub aes_key_ptr: *mut c_char, - pub aes_nonce_ptr: *mut c_char, + pub aes_nonce_ptr: *mut c_uchar, + pub aes_nonce_ptr_length: usize } #[no_mangle] @@ -41,13 +42,17 @@ pub extern "C" fn aes_256_key_and_nonce_from_x25519_diffie_hellman_shared_secret unsafe { std::slice::from_raw_parts(shared_secret, shared_secret_length) }; let aes_key = Key::::from_slice(&shared_secret_slice); - let mut aes_nonce: [u8; 8] = Default::default(); - aes_nonce.copy_from_slice(&shared_secret_slice[..8]); - + let mut aes_nonce = Vec::with_capacity(12); + aes_nonce.resize(12, 0); + aes_nonce.copy_from_slice(&shared_secret_slice[..12]); + let capacity = aes_nonce.capacity(); + aes_nonce.reserve_exact(capacity); let result = AesNonceAndKeyFromX25519DiffieHellman { aes_key_ptr: CString::new(base64::encode(aes_key)).unwrap().into_raw(), - aes_nonce_ptr: CString::new(base64::encode(aes_nonce)).unwrap().into_raw(), + aes_nonce_ptr: aes_nonce.as_mut_ptr(), + aes_nonce_ptr_length: aes_nonce.len() }; + std::mem::forget(aes_nonce); result } @@ -93,8 +98,7 @@ pub fn aes_256_key_and_nonce_from_x25519_diffie_hellman_shared_secret_test() { bob_shared_secret.shared_secret_length, ); - let alice_aes_nonce_cstr = unsafe { CString::from_raw(alice_aes.aes_nonce_ptr) }; - let alice_aes_nonce_ptr = alice_aes_nonce_cstr.as_bytes_with_nul().as_ptr() as *const c_char; + let alice_public_key_cstr = unsafe { CString::from_raw(alice_aes.aes_key_ptr) }; let alice_public_key_ptr = alice_public_key_cstr.as_bytes_with_nul().as_ptr() as *const c_char; @@ -102,15 +106,15 @@ pub fn aes_256_key_and_nonce_from_x25519_diffie_hellman_shared_secret_test() { let password = "DontUseThisPassword"; let password_cstr = password.as_bytes(); let password_ptr = password.as_ptr(); - let cipher_text_result = aes_256_encrypt_bytes_with_key(alice_aes_nonce_ptr, alice_public_key_ptr, password_ptr, password_cstr.len()); - let plain_text_result = aes_256_decrypt_bytes_with_key(bob_aes.aes_nonce_ptr, bob_aes.aes_key_ptr, cipher_text_result.ciphertext, cipher_text_result.length); + let cipher_text_result = aes_256_encrypt_bytes_with_key(alice_aes.aes_nonce_ptr, alice_aes.aes_nonce_ptr_length, alice_public_key_ptr, password_ptr, password_cstr.len()); + let plain_text_result = aes_256_decrypt_bytes_with_key(bob_aes.aes_nonce_ptr, bob_aes.aes_nonce_ptr_length, bob_aes.aes_key_ptr, cipher_text_result.ciphertext, cipher_text_result.length); let plain_text_result_slice: &[u8] = unsafe { - std::slice::from_raw_parts( - plain_text_result.plaintext, - plain_text_result.length, - ) - }; - assert_eq!(password_cstr, plain_text_result_slice); + std::slice::from_raw_parts( + plain_text_result.plaintext, + plain_text_result.length, + ) + }; + assert_eq!(password_cstr, plain_text_result_slice); } #[no_mangle] @@ -124,13 +128,17 @@ pub extern "C" fn aes_128_key_and_nonce_from_x25519_diffie_hellman_shared_secret let mut shorted_shared_secret: [u8; 16] = Default::default(); shorted_shared_secret.copy_from_slice(&shared_secret_slice[..16]); let aes_key = Key::::from_slice(&shorted_shared_secret); - let mut aes_nonce: [u8; 8] = Default::default(); - aes_nonce.copy_from_slice(&shared_secret_slice[..8]); - + let mut aes_nonce = Vec::with_capacity(12); + aes_nonce.resize(12, 0); + aes_nonce.copy_from_slice(&shared_secret_slice[..12]); + let capacity = aes_nonce.capacity(); + aes_nonce.reserve_exact(capacity); let result = AesNonceAndKeyFromX25519DiffieHellman { aes_key_ptr: CString::new(base64::encode(aes_key)).unwrap().into_raw(), - aes_nonce_ptr: CString::new(base64::encode(aes_nonce)).unwrap().into_raw(), + aes_nonce_ptr: aes_nonce.as_mut_ptr(), + aes_nonce_ptr_length: aes_nonce.len() }; + std::mem::forget(aes_nonce); result } @@ -176,8 +184,6 @@ pub fn aes_128_key_and_nonce_from_x25519_diffie_hellman_shared_secret_test() { bob_shared_secret.shared_secret_length, ); - let alice_aes_nonce_cstr = unsafe { CString::from_raw(alice_aes.aes_nonce_ptr) }; - let alice_aes_nonce_ptr = alice_aes_nonce_cstr.as_bytes_with_nul().as_ptr() as *const c_char; let alice_public_key_cstr = unsafe { CString::from_raw(alice_aes.aes_key_ptr) }; let alice_public_key_ptr = alice_public_key_cstr.as_bytes_with_nul().as_ptr() as *const c_char; @@ -185,8 +191,8 @@ pub fn aes_128_key_and_nonce_from_x25519_diffie_hellman_shared_secret_test() { let password = "DontUseThisPassword"; let password_cstr = password.as_bytes(); let password_ptr = password.as_ptr(); - let cipher_text_result = aes_128_encrypt_bytes_with_key(alice_aes_nonce_ptr, alice_public_key_ptr, password_ptr, password_cstr.len()); - let plain_text_result = aes_128_decrypt_bytes_with_key(bob_aes.aes_nonce_ptr, bob_aes.aes_key_ptr, cipher_text_result.ciphertext, cipher_text_result.length); + let cipher_text_result = aes_128_encrypt_bytes_with_key(alice_aes.aes_nonce_ptr, alice_aes.aes_nonce_ptr_length, alice_public_key_ptr, password_ptr, password_cstr.len()); + let plain_text_result = aes_128_decrypt_bytes_with_key(bob_aes.aes_nonce_ptr, bob_aes.aes_nonce_ptr_length, bob_aes.aes_key_ptr, cipher_text_result.ciphertext, cipher_text_result.length); let plain_text_result_slice: &[u8] = unsafe { std::slice::from_raw_parts( plain_text_result.plaintext,