Skip to content

#48 aes nonce at rust level #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 15, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 68 additions & 64 deletions src/aes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -23,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]
Expand All @@ -35,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::<Aes256Gcm>::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
}

Expand Down Expand Up @@ -87,24 +98,23 @@ 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;

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]
Expand All @@ -118,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::<Aes128Gcm>::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
}

Expand Down Expand Up @@ -170,17 +184,15 @@ 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;

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,
Expand All @@ -190,6 +202,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)))
Expand All @@ -206,19 +234,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)
Expand All @@ -230,7 +252,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<u8> = cipher.encrypt(nonce, to_encrypt_slice.as_ref()).unwrap();
let capacity = ciphertext.capacity();
ciphertext.reserve_exact(capacity);
Expand All @@ -244,19 +266,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)
Expand All @@ -267,7 +283,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);
Expand All @@ -281,19 +297,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)
Expand All @@ -304,7 +314,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);
Expand All @@ -318,19 +328,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)
Expand All @@ -341,7 +345,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);
Expand Down
Loading