diff --git a/Cargo.toml b/Cargo.toml index b7aad04..a11d4de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,25 +13,5 @@ crate-type = ["dylib"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -aes-gcm = "0.10.1" -argon2 = "0.4.1" -base64 = "0.20.0" -bcrypt = "0.13.0" -rand = "0.8.5" -rand_07 = { package = "rand", version = "0.7.0" } -rsa = "0.7.2" -scrypt = "0.10.0" -sha3 = "0.10.6" -hmac = "0.12.1" -sha2 = "0.10.6" -blake2 = "0.10.6" libc = "0.2.146" -rayon = "1.8.0" -x25519-dalek = {version = "2.0.0", features = ["static_secrets"]} -ascon-aead = "0.4.2" - -[profile.dev.package.num-bigint-dig] -opt-level = 3 - -[dependencies.ed25519-dalek] -version = "1" +cas-lib = "0.1.6" diff --git a/src/aes.rs b/src/aes.rs index 32f3b3e..62001e5 100644 --- a/src/aes.rs +++ b/src/aes.rs @@ -1,10 +1,5 @@ -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 cas_lib::symmetric::{aes::{CASAES128, CASAES256}, cas_symmetric_encryption::CASAESEncryption}; +use std::ffi::c_uchar; use crate::x25519; @@ -45,8 +40,8 @@ pub extern "C" fn aes_256_key_and_nonce_from_x25519_diffie_hellman_shared_secret shared_secret: *const c_uchar, shared_secret_length: usize, ) -> AesNonceAndKeyFromX25519DiffieHellman { - let shared_secret_slice: &[u8] = - unsafe { std::slice::from_raw_parts(shared_secret, shared_secret_length) }; + let shared_secret_slice: Vec = + unsafe { std::slice::from_raw_parts(shared_secret, shared_secret_length) }.to_vec(); let mut aes_nonce = Vec::with_capacity(12); aes_nonce.resize(12, 0); @@ -54,7 +49,36 @@ pub extern "C" fn aes_256_key_and_nonce_from_x25519_diffie_hellman_shared_secret let capacity = aes_nonce.capacity(); aes_nonce.reserve_exact(capacity); - let mut aes_key = Key::::from_slice(&shared_secret_slice).to_vec(); + let mut aes_key = ::key_from_vec(shared_secret_slice); + let aes_key_capacity = aes_key.capacity(); + aes_key.reserve_exact(aes_key_capacity); + + let result = AesNonceAndKeyFromX25519DiffieHellman { + aes_key_ptr: aes_key.as_mut_ptr(), + aes_key_ptr_length: aes_key.len(), + aes_nonce_ptr: aes_nonce.as_mut_ptr(), + aes_nonce_ptr_length: aes_nonce.len() + }; + std::mem::forget(aes_nonce); + std::mem::forget(aes_key); + result +} + +#[no_mangle] +pub extern "C" fn aes_256_key_and_nonce_from_x25519_diffie_hellman_shared_secret_threadpool( + shared_secret: *const c_uchar, + shared_secret_length: usize, +) -> AesNonceAndKeyFromX25519DiffieHellman { + let shared_secret_slice: Vec = + unsafe { std::slice::from_raw_parts(shared_secret, shared_secret_length) }.to_vec(); + + 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 mut aes_key = ::key_from_vec_threadpool(shared_secret_slice); let aes_key_capacity = aes_key.capacity(); aes_key.reserve_exact(aes_key_capacity); @@ -130,8 +154,8 @@ pub extern "C" fn aes_128_key_and_nonce_from_x25519_diffie_hellman_shared_secret shared_secret: *const c_uchar, shared_secret_length: usize, ) -> AesNonceAndKeyFromX25519DiffieHellman { - let shared_secret_slice: &[u8] = - unsafe { std::slice::from_raw_parts(shared_secret, shared_secret_length) }; + let shared_secret_slice: Vec = + unsafe { std::slice::from_raw_parts(shared_secret, shared_secret_length) }.to_vec(); let mut shorted_shared_secret: [u8; 16] = Default::default(); shorted_shared_secret.copy_from_slice(&shared_secret_slice[..16]); @@ -141,7 +165,38 @@ pub extern "C" fn aes_128_key_and_nonce_from_x25519_diffie_hellman_shared_secret let capacity = aes_nonce.capacity(); aes_nonce.reserve_exact(capacity); - let mut aes_key = Key::::from_slice(&shorted_shared_secret).to_vec(); + let mut aes_key = ::key_from_vec(shorted_shared_secret.to_vec()); + let aes_key_capacity = aes_key.capacity(); + aes_key.reserve_exact(aes_key_capacity); + + let result = AesNonceAndKeyFromX25519DiffieHellman { + aes_key_ptr: aes_key.as_mut_ptr(), + aes_key_ptr_length: aes_key.len(), + aes_nonce_ptr: aes_nonce.as_mut_ptr(), + aes_nonce_ptr_length: aes_nonce.len() + }; + std::mem::forget(aes_nonce); + std::mem::forget(aes_key); + result +} + +#[no_mangle] +pub extern "C" fn aes_128_key_and_nonce_from_x25519_diffie_hellman_shared_secret_threadpool( + shared_secret: *const c_uchar, + shared_secret_length: usize, +) -> AesNonceAndKeyFromX25519DiffieHellman { + let shared_secret_slice: Vec = + unsafe { std::slice::from_raw_parts(shared_secret, shared_secret_length) }.to_vec(); + + let mut shorted_shared_secret: [u8; 16] = Default::default(); + shorted_shared_secret.copy_from_slice(&shared_secret_slice[..16]); + 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 mut aes_key = ::key_from_vec_threadpool(shorted_shared_secret.to_vec()); let aes_key_capacity = aes_key.capacity(); aes_key.reserve_exact(aes_key_capacity); @@ -214,10 +269,20 @@ pub fn aes_128_key_and_nonce_from_x25519_diffie_hellman_shared_secret_test() { #[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 mut random_bytes = ::generate_nonce(); + 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_nonce_threadpool() -> AesNonce { + let mut random_bytes = ::generate_nonce_threadpool(); let capacity = random_bytes.capacity(); random_bytes.reserve_exact(capacity); let result = AesNonce { @@ -230,7 +295,20 @@ pub extern "C" fn aes_nonce() -> AesNonce { #[no_mangle] pub extern "C" fn aes_256_key() -> AesKeyResult { - let mut key = Aes256Gcm::generate_key(&mut OsRng).to_vec(); + let mut key = ::generate_key(); + let capacity = key.capacity(); + key.reserve_exact(capacity); + let result = AesKeyResult { + key: key.as_mut_ptr(), + length: key.len() + }; + std::mem::forget(key); + result +} + +#[no_mangle] +pub extern "C" fn aes_256_key_threadpool() -> AesKeyResult { + let mut key = ::generate_key_threadpool(); let capacity = key.capacity(); key.reserve_exact(capacity); let result = AesKeyResult { @@ -243,7 +321,20 @@ pub extern "C" fn aes_256_key() -> AesKeyResult { #[no_mangle] pub extern "C" fn aes_128_key() -> AesKeyResult { - let mut key = Aes128Gcm::generate_key(&mut OsRng).to_vec(); + let mut key = ::generate_key(); + let capacity = key.capacity(); + key.reserve_exact(capacity); + let result = AesKeyResult { + key: key.as_mut_ptr(), + length: key.len() + }; + std::mem::forget(key); + result +} + +#[no_mangle] +pub extern "C" fn aes_128_key_threadpool() -> AesKeyResult { + let mut key = ::generate_key_threadpool(); let capacity = key.capacity(); key.reserve_exact(capacity); let result = AesKeyResult { @@ -254,6 +345,7 @@ pub extern "C" fn aes_128_key() -> AesKeyResult { result } + #[no_mangle] pub extern "C" fn aes_128_encrypt_bytes_with_key( nonce_key: *const c_uchar, @@ -263,14 +355,35 @@ pub extern "C" fn aes_128_encrypt_bytes_with_key( to_encrypt: *const c_uchar, to_encrypt_length: usize, ) -> AesBytesEncrypt { - let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }; - let key_slice = unsafe {std::slice::from_raw_parts(key, key_length)}; - let to_encrypt_slice: &[u8] = - unsafe { std::slice::from_raw_parts(to_encrypt, to_encrypt_length) }; - let key = GenericArray::from_slice(key_slice); - let mut cipher = Aes128Gcm::new(&key); - 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 nonce_slice: Vec = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }.to_vec(); + let key_slice: Vec = unsafe {std::slice::from_raw_parts(key, key_length)}.to_vec(); + let to_encrypt_slice: Vec = + unsafe { std::slice::from_raw_parts(to_encrypt, to_encrypt_length) }.to_vec(); + let mut ciphertext = ::encrypt_plaintext(key_slice, nonce_slice, to_encrypt_slice); + let capacity = ciphertext.capacity(); + ciphertext.reserve_exact(capacity); + let result = AesBytesEncrypt { + ciphertext: ciphertext.as_mut_ptr(), + length: ciphertext.len(), + }; + std::mem::forget(ciphertext); + return result; +} + +#[no_mangle] +pub extern "C" fn aes_128_encrypt_bytes_with_key_threadpool( + nonce_key: *const c_uchar, + nonce_key_length: usize, + key: *const c_uchar, + key_length: usize, + to_encrypt: *const c_uchar, + to_encrypt_length: usize, +) -> AesBytesEncrypt { + let nonce_slice: Vec = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }.to_vec(); + let key_slice: Vec = unsafe {std::slice::from_raw_parts(key, key_length)}.to_vec(); + let to_encrypt_slice: Vec = + unsafe { std::slice::from_raw_parts(to_encrypt, to_encrypt_length) }.to_vec(); + let mut ciphertext = ::encrypt_plaintext_threadpool(key_slice, nonce_slice, to_encrypt_slice); let capacity = ciphertext.capacity(); ciphertext.reserve_exact(capacity); let result = AesBytesEncrypt { @@ -287,16 +400,36 @@ pub extern "C" fn aes_256_encrypt_bytes_with_key( nonce_key_length: usize, key: *const c_uchar, key_length: usize, - to_decrypt: *const c_uchar, - to_decrypt_length: usize, + to_encrypt: *const c_uchar, + to_encrypt_length: usize, ) -> AesBytesEncrypt { - let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }; - let key_slice = unsafe {std::slice::from_raw_parts(key, key_length)}; - let to_decrypt_slice = unsafe { std::slice::from_raw_parts(to_decrypt, to_decrypt_length) }; - let key = GenericArray::from_slice(key_slice); - let mut cipher = Aes256Gcm::new(&key); - let nonce = Nonce::from_slice(nonce_slice); // 96-bits; unique per message - let mut ciphertext = cipher.encrypt(nonce, to_decrypt_slice).unwrap(); + let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }.to_vec(); + let key_slice = unsafe {std::slice::from_raw_parts(key, key_length)}.to_vec(); + let to_encrypt_slice = unsafe { std::slice::from_raw_parts(to_encrypt, to_encrypt_length) }.to_vec(); + let mut ciphertext = ::encrypt_plaintext(key_slice, nonce_slice, to_encrypt_slice); + let capacity = ciphertext.capacity(); + ciphertext.reserve_exact(capacity); + let result = AesBytesEncrypt { + ciphertext: ciphertext.as_mut_ptr(), + length: ciphertext.len(), + }; + std::mem::forget(ciphertext); + return result; +} + +#[no_mangle] +pub extern "C" fn aes_256_encrypt_bytes_with_key_threadpool( + nonce_key: *const c_uchar, + nonce_key_length: usize, + key: *const c_uchar, + key_length: usize, + to_encrypt: *const c_uchar, + to_encrypt_length: usize, +) -> AesBytesEncrypt { + let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }.to_vec(); + let key_slice = unsafe {std::slice::from_raw_parts(key, key_length)}.to_vec(); + let to_encrypt_slice = unsafe { std::slice::from_raw_parts(to_encrypt, to_encrypt_length) }.to_vec(); + let mut ciphertext = ::encrypt_plaintext_threadpool(key_slice, nonce_slice, to_encrypt_slice); let capacity = ciphertext.capacity(); ciphertext.reserve_exact(capacity); let result = AesBytesEncrypt { @@ -316,13 +449,33 @@ pub extern "C" fn aes_128_decrypt_bytes_with_key( to_decrypt: *const c_uchar, to_decrypt_length: usize, ) -> AesBytesDecrypt { - let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }; - let key_slice = unsafe {std::slice::from_raw_parts(key, key_length)}; - let to_decrypt_slice = unsafe { std::slice::from_raw_parts(to_decrypt, to_decrypt_length) }; - let key = GenericArray::from_slice(key_slice); - let mut cipher = Aes128Gcm::new(&key); - let nonce = Nonce::from_slice(nonce_slice); // 96-bits; unique per message - let mut plaintext = cipher.decrypt(nonce, to_decrypt_slice).unwrap(); + let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }.to_vec(); + let key_slice = unsafe {std::slice::from_raw_parts(key, key_length)}.to_vec(); + let to_decrypt_slice = unsafe { std::slice::from_raw_parts(to_decrypt, to_decrypt_length) }.to_vec(); + let mut plaintext = ::decrypt_ciphertext(key_slice, nonce_slice, to_decrypt_slice); + let capacity = plaintext.capacity(); + plaintext.reserve_exact(capacity); + let result = AesBytesDecrypt { + plaintext: plaintext.as_mut_ptr(), + length: plaintext.len(), + }; + std::mem::forget(plaintext); + return result; +} + +#[no_mangle] +pub extern "C" fn aes_128_decrypt_bytes_with_key_threadpool( + nonce_key: *const c_uchar, + nonce_key_length: usize, + key: *const c_uchar, + key_length: usize, + to_decrypt: *const c_uchar, + to_decrypt_length: usize, +) -> AesBytesDecrypt { + let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }.to_vec(); + let key_slice = unsafe {std::slice::from_raw_parts(key, key_length)}.to_vec(); + let to_decrypt_slice = unsafe { std::slice::from_raw_parts(to_decrypt, to_decrypt_length) }.to_vec(); + let mut plaintext = ::decrypt_ciphertext_threadpool(key_slice, nonce_slice, to_decrypt_slice); let capacity = plaintext.capacity(); plaintext.reserve_exact(capacity); let result = AesBytesDecrypt { @@ -342,13 +495,33 @@ pub extern "C" fn aes_256_decrypt_bytes_with_key( to_decrypt: *const c_uchar, to_decrypt_length: usize, ) -> AesBytesDecrypt { - let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }; - let key_slice = unsafe {std::slice::from_raw_parts(key, key_length)}; - let to_decrypt_slice = unsafe { std::slice::from_raw_parts(to_decrypt, to_decrypt_length) }; - let key = GenericArray::from_slice(key_slice); - let mut cipher = Aes256Gcm::new(&key); - let nonce = Nonce::from_slice(nonce_slice); // 96-bits; unique per message - let mut plaintext = cipher.decrypt(nonce, to_decrypt_slice).unwrap(); + let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }.to_vec(); + let key_slice = unsafe {std::slice::from_raw_parts(key, key_length)}.to_vec(); + let to_decrypt_slice = unsafe { std::slice::from_raw_parts(to_decrypt, to_decrypt_length) }.to_vec(); + let mut plaintext = ::decrypt_ciphertext(key_slice, nonce_slice, to_decrypt_slice); + let capacity = plaintext.capacity(); + plaintext.reserve_exact(capacity); + let result = AesBytesDecrypt { + plaintext: plaintext.as_mut_ptr(), + length: plaintext.len(), + }; + std::mem::forget(plaintext); + return result; +} + +#[no_mangle] +pub extern "C" fn aes_256_decrypt_bytes_with_key_threadpool( + nonce_key: *const c_uchar, + nonce_key_length: usize, + key: *const c_uchar, + key_length: usize, + to_decrypt: *const c_uchar, + to_decrypt_length: usize, +) -> AesBytesDecrypt { + let nonce_slice = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }.to_vec(); + let key_slice = unsafe {std::slice::from_raw_parts(key, key_length)}.to_vec(); + let to_decrypt_slice = unsafe { std::slice::from_raw_parts(to_decrypt, to_decrypt_length) }.to_vec(); + let mut plaintext = ::decrypt_ciphertext_threadpool(key_slice, nonce_slice, to_decrypt_slice); let capacity = plaintext.capacity(); plaintext.reserve_exact(capacity); let result = AesBytesDecrypt { diff --git a/src/ascon_aead.rs b/src/ascon_aead.rs index bbf96bb..b3c15ee 100644 --- a/src/ascon_aead.rs +++ b/src/ascon_aead.rs @@ -1,7 +1,6 @@ use std::ffi::{c_char, c_uchar, CStr, CString}; - -use ascon_aead::aead::{generic_array::GenericArray, Aead, AeadCore, KeyInit, OsRng}; -use ascon_aead::Ascon128; +use cas_lib::sponges::ascon_aead::AsconAead; +use cas_lib::sponges::cas_ascon_aead::{CASAsconAead}; #[repr(C)] pub struct Ascon128EncryptResult { @@ -15,39 +14,85 @@ pub struct Ascon128DecryptResult { length: usize, } +#[repr(C)] +pub struct Ascon128Key { + key: *mut c_uchar, + length: usize +} + +#[repr(C)] +pub struct Ascon128Nonce { + nonce: *mut c_uchar, + length: usize +} + #[no_mangle] -pub extern "C" fn ascon_128_key() -> *mut c_char { - return CString::new(base64::encode(Ascon128::generate_key(&mut OsRng))) - .unwrap() - .into_raw(); +pub extern "C" fn ascon_128_key() -> Ascon128Key { + let mut key = ::generate_key(); + let capacity = key.capacity(); + key.reserve_exact(capacity); + let result = Ascon128Key { + key: key.as_mut_ptr(), + length: key.len() + }; + std::mem::forget(key); + result } #[no_mangle] -pub extern "C" fn ascon_128_nonce() -> *mut c_char { - return CString::new(base64::encode(Ascon128::generate_nonce(&mut OsRng))) - .unwrap() - .into_raw(); +pub extern "C" fn ascon_128_key_threadpool() -> Ascon128Key { + let mut key = ::generate_key_threadpool(); + let capacity = key.capacity(); + key.reserve_exact(capacity); + let result = Ascon128Key { + key: key.as_mut_ptr(), + length: key.len() + }; + std::mem::forget(key); + result +} + + + +#[no_mangle] +pub extern "C" fn ascon_128_nonce() -> Ascon128Nonce { + let mut nonce = ::generate_nonce(); + let capacity = nonce.capacity(); + nonce.reserve_exact(capacity); + let result = Ascon128Nonce { + nonce: nonce.as_mut_ptr(), + length: nonce.len() + }; + std::mem::forget(nonce); + result +} + +#[no_mangle] +pub extern "C" fn ascon_128_nonce_threadpool() -> Ascon128Nonce { + let mut nonce = ::generate_nonce_threadpool(); + let capacity = nonce.capacity(); + nonce.reserve_exact(capacity); + let result = Ascon128Nonce { + nonce: nonce.as_mut_ptr(), + length: nonce.len() + }; + std::mem::forget(nonce); + result } #[no_mangle] pub extern "C" fn ascon_128_encrypt( - nonce_key: *const c_char, - key: *const c_char, + nonce_key: *const c_uchar, + nonce_key_length: usize, + key: *const c_uchar, + key_length: usize, to_encrypt: *const c_uchar, to_encrypt_length: usize, ) -> Ascon128EncryptResult { - let nonce_key = unsafe { CStr::from_ptr(nonce_key) }.to_str().unwrap(); - let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap(); - let to_encrypt = unsafe { std::slice::from_raw_parts(to_encrypt, to_encrypt_length) }; - - let decoded_nonce_key = base64::decode(nonce_key).unwrap(); - let decoded_key = base64::decode(key).unwrap(); - - let key = GenericArray::from_slice(&decoded_nonce_key); - let nonce_key = GenericArray::from_slice(&decoded_key); - - let cipher = Ascon128::new(key); - let mut ciphertext = cipher.encrypt(&nonce_key, to_encrypt.as_ref()).unwrap(); + let nonce_key = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }.to_vec(); + let key = unsafe { std::slice::from_raw_parts(key, key_length) }.to_vec(); + let to_encrypt = unsafe { std::slice::from_raw_parts(to_encrypt, to_encrypt_length) }.to_vec(); + let mut ciphertext = ::encrypt(key, nonce_key, to_encrypt); let capacity = ciphertext.capacity(); ciphertext.reserve_exact(capacity); let result = Ascon128EncryptResult { @@ -58,26 +103,66 @@ pub extern "C" fn ascon_128_encrypt( result } - #[no_mangle] -pub extern "C" fn ascon_128_decrypt( - nonce_key: *const c_char, - key: *const c_char, +pub extern "C" fn ascon_128_encrypt_threadpool( + nonce_key: *const c_uchar, + nonce_key_length: usize, + key: *const c_uchar, + key_length: usize, to_encrypt: *const c_uchar, to_encrypt_length: usize, -) -> Ascon128DecryptResult { - let nonce_key = unsafe { CStr::from_ptr(nonce_key) }.to_str().unwrap(); - let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap(); - let to_encrypt = unsafe { std::slice::from_raw_parts(to_encrypt, to_encrypt_length) }; +) -> Ascon128EncryptResult { + let nonce_key = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }.to_vec(); + let key = unsafe { std::slice::from_raw_parts(key, key_length) }.to_vec(); + let to_encrypt = unsafe { std::slice::from_raw_parts(to_encrypt, to_encrypt_length) }.to_vec(); + let mut ciphertext = ::encrypt_threadpool(key, nonce_key, to_encrypt); + let capacity = ciphertext.capacity(); + ciphertext.reserve_exact(capacity); + let result = Ascon128EncryptResult { + ciphertext: ciphertext.as_mut_ptr(), + length: ciphertext.len(), + }; + std::mem::forget(ciphertext); + result +} - let decoded_nonce_key = base64::decode(nonce_key).unwrap(); - let decoded_key = base64::decode(key).unwrap(); - let key = GenericArray::from_slice(&decoded_nonce_key); - let nonce_key = GenericArray::from_slice(&decoded_key); +#[no_mangle] +pub extern "C" fn ascon_128_decrypt( + nonce_key: *const c_uchar, + nonce_key_length: usize, + key: *const c_uchar, + key_length: usize, + to_decrypt: *const c_uchar, + to_decrypt_length: usize, +) -> Ascon128DecryptResult { + let nonce_key = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }.to_vec(); + let key = unsafe { std::slice::from_raw_parts(key, key_length) }.to_vec(); + let to_decrypt = unsafe { std::slice::from_raw_parts(to_decrypt, to_decrypt_length) }.to_vec(); + let mut plaintext = ::decrypt(key, nonce_key, to_decrypt); + let capacity = plaintext.capacity(); + plaintext.reserve_exact(capacity); + let result = Ascon128DecryptResult { + plaintext: plaintext.as_mut_ptr(), + length: plaintext.len(), + }; + std::mem::forget(plaintext); + result +} - let cipher = Ascon128::new(key); - let mut plaintext = cipher.decrypt(&nonce_key, to_encrypt.as_ref()).unwrap(); +#[no_mangle] +pub extern "C" fn ascon_128_decrypt_threadpool( + nonce_key: *const c_uchar, + nonce_key_length: usize, + key: *const c_uchar, + key_length: usize, + to_decrypt: *const c_uchar, + to_decrypt_length: usize, +) -> Ascon128DecryptResult { + let nonce_key = unsafe { std::slice::from_raw_parts(nonce_key, nonce_key_length) }.to_vec(); + let key = unsafe { std::slice::from_raw_parts(key, key_length) }.to_vec(); + let to_decrypt = unsafe { std::slice::from_raw_parts(to_decrypt, to_decrypt_length) }.to_vec(); + let mut plaintext = ::decrypt_threadpool(key, nonce_key, to_decrypt); let capacity = plaintext.capacity(); plaintext.reserve_exact(capacity); let result = Ascon128DecryptResult { diff --git a/src/blake2.rs b/src/blake2.rs deleted file mode 100644 index 6dafcd8..0000000 --- a/src/blake2.rs +++ /dev/null @@ -1,135 +0,0 @@ -use core::slice; -use std::ffi::c_uchar; - -use blake2::{Blake2b512, Blake2s256, Digest}; - -#[repr(C)] -pub struct Blake2HashByteResult { - pub result_bytes_ptr: *mut c_uchar, - pub length: usize, -} - -#[no_mangle] -pub extern "C" fn blake2_512_bytes( - data: *const c_uchar, - data_length: usize, -) -> Blake2HashByteResult { - let data_slice = unsafe { - assert!(!data.is_null()); - std::slice::from_raw_parts(data, data_length) - }; - - let mut hasher = Blake2b512::new(); - hasher.update(data_slice); - let result = hasher.finalize(); - return unsafe { - let size_of_result = std::mem::size_of_val(&result); - let result_raw_ptr = libc::malloc(size_of_result) as *mut c_uchar; - std::ptr::copy_nonoverlapping(result.as_ptr(), result_raw_ptr, size_of_result); - let result = Blake2HashByteResult { - result_bytes_ptr: result_raw_ptr, - length: size_of_result, - }; - result - }; -} - -#[test] -fn blake2_512_bytes_test() { - let data_to_hash = "Blake2512HashingTechnique"; - let data_to_hash_bytes = data_to_hash.as_bytes(); - let data_to_hash_length = data_to_hash_bytes.len(); - let result = blake2_512_bytes(data_to_hash_bytes.as_ptr(), data_to_hash_length); - let result_slice = unsafe { slice::from_raw_parts(result.result_bytes_ptr, result.length) }; - assert_ne!(data_to_hash_bytes, result_slice); -} - -#[no_mangle] -pub extern "C" fn blake2_512_bytes_verify( - hashed_data: *const c_uchar, - hashed_data_length: usize, - to_compare: *const c_uchar, - to_compare_length: usize, -) -> bool { - let data_slice = unsafe { - assert!(!hashed_data.is_null()); - std::slice::from_raw_parts(hashed_data, hashed_data_length) - }; - let to_compare_slice = unsafe { - assert!(!to_compare.is_null()); - std::slice::from_raw_parts(to_compare, to_compare_length) - }; - let mut hasher = Blake2b512::new(); - hasher.update(to_compare_slice); - let result = hasher.finalize(); - let result_slice: &[u8] = result.as_ref(); - return result_slice.eq(data_slice); -} - -#[no_mangle] -pub extern "C" fn blake2_256_bytes( - data_to_hash: *const c_uchar, - data_to_hash_length: usize, -) -> Blake2HashByteResult { - let data_to_hash_slice = unsafe { - assert!(!data_to_hash.is_null()); - std::slice::from_raw_parts(data_to_hash, data_to_hash_length) - }; - let mut hasher = Blake2s256::new(); - hasher.update(data_to_hash_slice); - let result = hasher.finalize(); - return unsafe { - let size_of_result = std::mem::size_of_val(&result); - let result_raw_ptr = libc::malloc(size_of_result) as *mut c_uchar; - std::ptr::copy_nonoverlapping(result.as_ptr(), result_raw_ptr, size_of_result); - let result = Blake2HashByteResult { - result_bytes_ptr: result_raw_ptr, - length: size_of_result, - }; - result - }; -} - -#[test] -fn blake2_256_bytes_test() { - let data_to_hash = "Blake2256HashingTechnique"; - let data_to_hash_bytes = data_to_hash.as_bytes(); - let data_to_hash_length = data_to_hash_bytes.len(); - let result: Blake2HashByteResult = - blake2_256_bytes(data_to_hash_bytes.as_ptr(), data_to_hash_length); - let result_slice = unsafe { slice::from_raw_parts(result.result_bytes_ptr, result.length) }; - assert_ne!(data_to_hash_bytes, result_slice); -} - -#[no_mangle] -pub extern "C" fn blake2_256_bytes_verify( - hashed_data: *const c_uchar, - hashed_data_length: usize, - to_compare: *const c_uchar, - to_compare_length: usize, -) -> bool { - let data_slice = unsafe { - assert!(!hashed_data.is_null()); - std::slice::from_raw_parts(hashed_data, hashed_data_length) - }; - let to_compare_slice = unsafe { - assert!(!to_compare.is_null()); - std::slice::from_raw_parts(to_compare, to_compare_length) - }; - let mut hasher = Blake2s256::new(); - hasher.update(to_compare_slice); - let result = hasher.finalize(); - let result_slice: &[u8] = result.as_ref(); - return result_slice.eq(data_slice); -} - -#[test] -fn blake2_256_bytes_verify_test() { - let data_to_hash = "Blake2512HashingTechnique"; - let data_to_hash_bytes = data_to_hash.as_bytes(); - let data_to_hash_length = data_to_hash_bytes.len(); - let result: Blake2HashByteResult = - blake2_256_bytes(data_to_hash_bytes.as_ptr(), data_to_hash_length); - let result_slice = unsafe { slice::from_raw_parts(result.result_bytes_ptr, result.length) }; - assert_ne!(data_to_hash_bytes, result_slice); -} diff --git a/src/blake2/mod.rs b/src/blake2/mod.rs new file mode 100644 index 0000000..df9af5e --- /dev/null +++ b/src/blake2/mod.rs @@ -0,0 +1,207 @@ +use std::{ffi::c_uchar, slice, sync::mpsc}; + +use cas_lib::hashers::{blake2::CASBlake2, cas_hasher::CASHasher}; + +mod types; +use self::types::Blake2HashByteResult; + +#[no_mangle] +pub extern "C" fn blake2_512_bytes( + data: *const c_uchar, + data_length: usize, +) -> Blake2HashByteResult { + let data_slice = unsafe { + assert!(!data.is_null()); + std::slice::from_raw_parts(data, data_length) + } + .to_vec(); + + let mut result: Vec = ::hash_512(data_slice); + let capacity = result.capacity(); + result.reserve_exact(capacity); + let return_result = Blake2HashByteResult { + result_bytes_ptr: result.as_mut_ptr(), + length: result.len(), + }; + std::mem::forget(result); + return_result +} + +#[no_mangle] +pub extern "C" fn blake2_512_bytes_threadpool( + data: *const c_uchar, + data_length: usize, +) -> Blake2HashByteResult { + let data_slice = unsafe { + assert!(!data.is_null()); + std::slice::from_raw_parts(data, data_length) + } + .to_vec(); + let mut result: Vec = ::hash_512_threadpool(data_slice); + let capacity = result.capacity(); + result.reserve_exact(capacity); + let return_result = Blake2HashByteResult { + result_bytes_ptr: result.as_mut_ptr(), + length: result.len(), + }; + std::mem::forget(result); + return_result +} + +#[test] +fn blake2_512_bytes_test() { + let data_to_hash = "Blake2512HashingTechnique"; + let data_to_hash_bytes = data_to_hash.as_bytes(); + let data_to_hash_length = data_to_hash_bytes.len(); + let result = blake2_512_bytes(data_to_hash_bytes.as_ptr(), data_to_hash_length); + let result_slice = unsafe { slice::from_raw_parts(result.result_bytes_ptr, result.length) }; + assert_ne!(data_to_hash_bytes, result_slice); +} + +#[no_mangle] +pub extern "C" fn blake2_512_bytes_verify( + hashed_data: *const c_uchar, + hashed_data_length: usize, + to_compare: *const c_uchar, + to_compare_length: usize, +) -> bool { + let data_slice = unsafe { + assert!(!hashed_data.is_null()); + std::slice::from_raw_parts(hashed_data, hashed_data_length) + } + .to_vec(); + let to_compare_slice = unsafe { + assert!(!to_compare.is_null()); + std::slice::from_raw_parts(to_compare, to_compare_length) + } + .to_vec(); + return ::verify_512(data_slice, to_compare_slice); +} + +#[no_mangle] +pub extern "C" fn blake2_512_bytes_verify_threadpool( + hashed_data: *const c_uchar, + hashed_data_length: usize, + to_compare: *const c_uchar, + to_compare_length: usize, +) -> bool { + let data_slice = unsafe { + assert!(!hashed_data.is_null()); + std::slice::from_raw_parts(hashed_data, hashed_data_length) + } + .to_vec(); + let to_compare_slice = unsafe { + assert!(!to_compare.is_null()); + std::slice::from_raw_parts(to_compare, to_compare_length) + } + .to_vec(); + let result: bool = + ::verify_512_threadpool(data_slice, to_compare_slice); + result +} + +#[no_mangle] +pub extern "C" fn blake2_256_bytes( + data_to_hash: *const c_uchar, + data_to_hash_length: usize, +) -> Blake2HashByteResult { + let data_to_hash_slice = unsafe { + assert!(!data_to_hash.is_null()); + std::slice::from_raw_parts(data_to_hash, data_to_hash_length) + } + .to_vec(); + let mut result = ::hash_256(data_to_hash_slice); + let capacity = result.capacity(); + result.reserve_exact(capacity); + let return_result = Blake2HashByteResult { + result_bytes_ptr: result.as_mut_ptr(), + length: result.len(), + }; + std::mem::forget(result); + return return_result; +} + +#[no_mangle] +pub extern "C" fn blake2_256_bytes_threadpool( + data_to_hash: *const c_uchar, + data_to_hash_length: usize, +) -> Blake2HashByteResult { + let data_to_hash_slice = unsafe { + assert!(!data_to_hash.is_null()); + std::slice::from_raw_parts(data_to_hash, data_to_hash_length) + } + .to_vec(); + let mut result = ::hash_256_threadpool(data_to_hash_slice); + let capacity = result.capacity(); + result.reserve_exact(capacity); + let return_result = Blake2HashByteResult { + result_bytes_ptr: result.as_mut_ptr(), + length: result.len(), + }; + std::mem::forget(result); + return_result +} + +#[test] +fn blake2_256_bytes_test() { + let data_to_hash = "Blake2256HashingTechnique"; + let data_to_hash_bytes = data_to_hash.as_bytes(); + let data_to_hash_length = data_to_hash_bytes.len(); + let result: Blake2HashByteResult = + blake2_256_bytes(data_to_hash_bytes.as_ptr(), data_to_hash_length); + let result_slice = unsafe { slice::from_raw_parts(result.result_bytes_ptr, result.length) }; + assert_ne!(data_to_hash_bytes, result_slice); +} + +#[no_mangle] +pub extern "C" fn blake2_256_bytes_verify( + hashed_data: *const c_uchar, + hashed_data_length: usize, + to_compare: *const c_uchar, + to_compare_length: usize, +) -> bool { + let data_slice = unsafe { + assert!(!hashed_data.is_null()); + std::slice::from_raw_parts(hashed_data, hashed_data_length) + } + .to_vec(); + let to_compare_slice = unsafe { + assert!(!to_compare.is_null()); + std::slice::from_raw_parts(to_compare, to_compare_length) + } + .to_vec(); + let result = ::verify_256(data_slice, to_compare_slice); + result +} + +#[no_mangle] +pub extern "C" fn blake2_256_bytes_verify_threadpool( + hashed_data: *const c_uchar, + hashed_data_length: usize, + to_compare: *const c_uchar, + to_compare_length: usize, +) -> bool { + let data_slice = unsafe { + assert!(!hashed_data.is_null()); + std::slice::from_raw_parts(hashed_data, hashed_data_length) + } + .to_vec(); + let to_compare_slice = unsafe { + assert!(!to_compare.is_null()); + std::slice::from_raw_parts(to_compare, to_compare_length) + } + .to_vec(); + let result = ::verify_256_threadpool(data_slice, to_compare_slice); + result +} + +#[test] +fn blake2_256_bytes_verify_test() { + let data_to_hash = "Blake2512HashingTechnique"; + let data_to_hash_bytes = data_to_hash.as_bytes(); + let data_to_hash_length = data_to_hash_bytes.len(); + let result: Blake2HashByteResult = + blake2_256_bytes(data_to_hash_bytes.as_ptr(), data_to_hash_length); + let result_slice = unsafe { slice::from_raw_parts(result.result_bytes_ptr, result.length) }; + assert_ne!(data_to_hash_bytes, result_slice); +} diff --git a/src/blake2/types.rs b/src/blake2/types.rs new file mode 100644 index 0000000..9844a34 --- /dev/null +++ b/src/blake2/types.rs @@ -0,0 +1,7 @@ +use std::ffi::c_uchar; + +#[repr(C)] +pub struct Blake2HashByteResult { + pub result_bytes_ptr: *mut c_uchar, + pub length: usize, +} \ No newline at end of file diff --git a/src/digital_signature.rs b/src/digital_signature.rs index 8228695..29bf0ab 100644 --- a/src/digital_signature.rs +++ b/src/digital_signature.rs @@ -1,13 +1,12 @@ use std::ffi::{c_char, c_uchar, CStr, CString}; -use ed25519_dalek::{Keypair, Signature, Signer, Verifier}; -use rsa::{ - pkcs1::{DecodeRsaPublicKey, EncodeRsaPublicKey}, - pkcs8::EncodePrivateKey, - rand_core::OsRng, - PaddingScheme, PublicKey, RsaPrivateKey, RsaPublicKey, +use cas_lib::digital_signature::{ + cas_digital_signature_rsa::{ED25519DigitalSignature, RSADigitalSignature}, + sha_256_ed25519::SHA256ED25519DigitalSignature, + sha_256_rsa::SHA256RSADigitalSignature, + sha_512_ed25519::SHA512ED25519DigitalSignature, + sha_512_rsa::SHA512RSADigitalSignature, }; -use sha3::{Digest, Sha3_256, Sha3_512}; #[repr(C)] pub struct SHARSADigitalSignatureResult { @@ -32,39 +31,50 @@ pub extern "C" fn sha_512_rsa_digital_signature( data_length: usize, ) -> SHARSADigitalSignatureResult { assert!(!data_to_sign.is_null()); - let data_to_sign_slice = unsafe { std::slice::from_raw_parts(data_to_sign, data_length) }; + let data_to_sign_slice = + unsafe { std::slice::from_raw_parts(data_to_sign, data_length) }.to_vec(); if rsa_key_size != 1024 && rsa_key_size != 2048 && rsa_key_size != 4096 { panic!("Not a valid RSA key length"); } - let mut hasher = Sha3_512::new(); - hasher.update(data_to_sign_slice); - let sha_hasher_result = hasher.finalize(); - let mut rng: OsRng = OsRng; - let private_key: RsaPrivateKey = - RsaPrivateKey::new(&mut rng, rsa_key_size).expect("failed to generate a key"); - let public_key: RsaPublicKey = private_key.to_public_key(); - let mut signed_data = private_key - .sign(PaddingScheme::new_pkcs1v15_sign_raw(), &sha_hasher_result) - .unwrap(); + let result = ::digital_signature_rsa( + rsa_key_size as u32, + data_to_sign_slice, + ); + let mut signed_data = result.signature; let capacity = signed_data.capacity(); signed_data.reserve_exact(capacity); let result = SHARSADigitalSignatureResult { - public_key: CString::new( - public_key - .to_pkcs1_pem(rsa::pkcs8::LineEnding::LF) - .unwrap() - .to_string(), - ) - .unwrap() - .into_raw(), - private_key: CString::new( - private_key - .to_pkcs8_pem(rsa::pkcs8::LineEnding::LF) - .unwrap() - .to_string(), - ) - .unwrap() - .into_raw(), + public_key: CString::new(result.public_key).unwrap().into_raw(), + private_key: CString::new(result.private_key).unwrap().into_raw(), + signature_raw_ptr: signed_data.as_mut_ptr(), + length: signed_data.len(), + }; + std::mem::forget(signed_data); + result +} + +#[no_mangle] +pub extern "C" fn sha_512_rsa_digital_signature_threadpool( + rsa_key_size: usize, + data_to_sign: *const c_uchar, + data_length: usize, +) -> SHARSADigitalSignatureResult { + assert!(!data_to_sign.is_null()); + let data_to_sign_slice = + unsafe { std::slice::from_raw_parts(data_to_sign, data_length) }.to_vec(); + if rsa_key_size != 1024 && rsa_key_size != 2048 && rsa_key_size != 4096 { + panic!("Not a valid RSA key length"); + } + let result = ::digital_signature_rsa_threadpool( + rsa_key_size as u32, + data_to_sign_slice, + ); + let mut signed_data = result.signature; + let capacity = signed_data.capacity(); + signed_data.reserve_exact(capacity); + let result = SHARSADigitalSignatureResult { + public_key: CString::new(result.public_key).unwrap().into_raw(), + private_key: CString::new(result.private_key).unwrap().into_raw(), signature_raw_ptr: signed_data.as_mut_ptr(), length: signed_data.len(), }; @@ -79,39 +89,50 @@ pub extern "C" fn sha_256_rsa_digital_signature( data_length: usize, ) -> SHARSADigitalSignatureResult { assert!(!data_to_sign.is_null()); - let data_to_sign_slice = unsafe { std::slice::from_raw_parts(data_to_sign, data_length) }; + let data_to_sign_slice = + unsafe { std::slice::from_raw_parts(data_to_sign, data_length) }.to_vec(); if rsa_key_size != 1024 && rsa_key_size != 2048 && rsa_key_size != 4096 { panic!("Not a valid RSA key length"); } - let mut hasher = Sha3_256::new(); - hasher.update(data_to_sign_slice); - let sha_hasher_result = hasher.finalize(); - let mut rng: OsRng = OsRng; - let private_key: RsaPrivateKey = - RsaPrivateKey::new(&mut rng, rsa_key_size).expect("failed to generate a key"); - let public_key: RsaPublicKey = private_key.to_public_key(); - let mut signed_data = private_key - .sign(PaddingScheme::new_pkcs1v15_sign_raw(), &sha_hasher_result) - .unwrap(); + let result = ::digital_signature_rsa( + rsa_key_size as u32, + data_to_sign_slice, + ); + let mut signed_data = result.signature; let capacity = signed_data.capacity(); signed_data.reserve_exact(capacity); let result = SHARSADigitalSignatureResult { - public_key: CString::new( - public_key - .to_pkcs1_pem(rsa::pkcs8::LineEnding::LF) - .unwrap() - .to_string(), - ) - .unwrap() - .into_raw(), - private_key: CString::new( - private_key - .to_pkcs8_pem(rsa::pkcs8::LineEnding::LF) - .unwrap() - .to_string(), - ) - .unwrap() - .into_raw(), + public_key: CString::new(result.public_key).unwrap().into_raw(), + private_key: CString::new(result.private_key).unwrap().into_raw(), + signature_raw_ptr: signed_data.as_mut_ptr(), + length: signed_data.len(), + }; + std::mem::forget(signed_data); + result +} + +#[no_mangle] +pub extern "C" fn sha_256_rsa_digital_signature_threadpool( + rsa_key_size: usize, + data_to_sign: *const c_uchar, + data_length: usize, +) -> SHARSADigitalSignatureResult { + assert!(!data_to_sign.is_null()); + let data_to_sign_slice = + unsafe { std::slice::from_raw_parts(data_to_sign, data_length) }.to_vec(); + if rsa_key_size != 1024 && rsa_key_size != 2048 && rsa_key_size != 4096 { + panic!("Not a valid RSA key length"); + } + let result = ::digital_signature_rsa_threadpool( + rsa_key_size as u32, + data_to_sign_slice, + ); + let mut signed_data = result.signature; + let capacity = signed_data.capacity(); + signed_data.reserve_exact(capacity); + let result = SHARSADigitalSignatureResult { + public_key: CString::new(result.public_key).unwrap().into_raw(), + private_key: CString::new(result.private_key).unwrap().into_raw(), signature_raw_ptr: signed_data.as_mut_ptr(), length: signed_data.len(), }; @@ -132,29 +153,57 @@ pub extern "C" fn sha_512_rsa_digital_signature_verify( CStr::from_ptr(public_key) } .to_str() - .unwrap(); - let data_to_verify_slice: &[u8] = unsafe { + .unwrap() + .to_string(); + let data_to_verify_slice: Vec = unsafe { assert!(!data_to_verify.is_null()); std::slice::from_raw_parts(data_to_verify, data_to_verify_length) - }; - let signature_slice: &[u8] = unsafe { + } + .to_vec(); + let signature_slice: Vec = unsafe { assert!(!signature.is_null()); std::slice::from_raw_parts(signature, signature_length) - }; - let mut hasher = Sha3_512::new(); - hasher.update(data_to_verify_slice); - let sha_hasher_result = hasher.finalize(); - let public_key = RsaPublicKey::from_pkcs1_pem(public_key_string).unwrap(); - let verified = public_key.verify( - PaddingScheme::new_pkcs1v15_sign_raw(), - &sha_hasher_result, - &signature_slice, + } + .to_vec(); + let result = ::verify_rsa( + public_key_string, + data_to_verify_slice, + signature_slice, ); - if verified.is_err() == false { - return true; - } else { - return false; + result +} + +#[no_mangle] +pub extern "C" fn sha_512_rsa_digital_signature_verify_threadpool( + public_key: *const c_char, + data_to_verify: *const c_uchar, + data_to_verify_length: usize, + signature: *const c_uchar, + signature_length: usize, +) -> bool { + let public_key_string = unsafe { + assert!(!public_key.is_null()); + CStr::from_ptr(public_key) + } + .to_str() + .unwrap() + .to_string(); + let data_to_verify_slice: Vec = unsafe { + assert!(!data_to_verify.is_null()); + std::slice::from_raw_parts(data_to_verify, data_to_verify_length) + } + .to_vec(); + let signature_slice: Vec = unsafe { + assert!(!signature.is_null()); + std::slice::from_raw_parts(signature, signature_length) } + .to_vec(); + let result = ::verify_rsa_threadpool( + public_key_string, + data_to_verify_slice, + signature_slice, + ); + result } #[no_mangle] @@ -170,29 +219,57 @@ pub extern "C" fn sha_256_rsa_digital_signature_verify( CStr::from_ptr(public_key) } .to_str() - .unwrap(); - let data_to_verify_slice: &[u8] = unsafe { + .unwrap() + .to_string(); + let data_to_verify_slice: Vec = unsafe { assert!(!data_to_verify.is_null()); std::slice::from_raw_parts(data_to_verify, data_to_verify_length) - }; - let signature_slice: &[u8] = unsafe { + } + .to_vec(); + let signature_slice: Vec = unsafe { assert!(!signature.is_null()); std::slice::from_raw_parts(signature, signature_length) - }; - let mut hasher = Sha3_256::new(); - hasher.update(data_to_verify_slice); - let sha_hasher_result = hasher.finalize(); - let public_key = RsaPublicKey::from_pkcs1_pem(public_key_string).unwrap(); - let verified = public_key.verify( - PaddingScheme::new_pkcs1v15_sign_raw(), - &sha_hasher_result, - &signature_slice, + } + .to_vec(); + let result = ::verify_rsa( + public_key_string, + data_to_verify_slice, + signature_slice, ); - if verified.is_err() == false { - return true; - } else { - return false; + result +} + +#[no_mangle] +pub extern "C" fn sha_256_rsa_digital_signature_verify_threadpool( + public_key: *const c_char, + data_to_verify: *const c_uchar, + data_to_verify_length: usize, + signature: *const c_uchar, + signature_length: usize, +) -> bool { + let public_key_string = unsafe { + assert!(!public_key.is_null()); + CStr::from_ptr(public_key) } + .to_str() + .unwrap() + .to_string(); + let data_to_verify_slice: Vec = unsafe { + assert!(!data_to_verify.is_null()); + std::slice::from_raw_parts(data_to_verify, data_to_verify_length) + } + .to_vec(); + let signature_slice: Vec = unsafe { + assert!(!signature.is_null()); + std::slice::from_raw_parts(signature, signature_length) + } + .to_vec(); + let result = ::verify_rsa_threadpool( + public_key_string, + data_to_verify_slice, + signature_slice, + ); + result } #[no_mangle] @@ -203,44 +280,58 @@ pub extern "C" fn sha512_ed25519_digital_signature( let data_to_sign_slice = unsafe { assert!(!data_to_sign.is_null()); std::slice::from_raw_parts(data_to_sign, data_length) - }; - - let mut hasher = Sha3_512::new(); - hasher.update(data_to_sign_slice); - let sha_hasher_result = hasher.finalize(); - - let mut csprng = rand_07::rngs::OsRng {}; - let keypair = Keypair::generate(&mut csprng); - - let signature = keypair.sign(&sha_hasher_result); - let signature_bytes = signature.to_bytes(); - let public_keypair_bytes = keypair.public.to_bytes(); - - return unsafe { - let size_of_public_key = std::mem::size_of_val(&public_keypair_bytes); - let public_key_raw_ptr = libc::malloc(size_of_public_key) as *mut c_uchar; - std::ptr::copy_nonoverlapping( - public_keypair_bytes.as_ptr(), - public_key_raw_ptr, - size_of_public_key, + } + .to_vec(); + let result = + ::digital_signature_ed25519( + data_to_sign_slice, ); + let mut public_key = result.public_key; + let public_key_capacity = public_key.capacity(); + public_key.reserve_exact(public_key_capacity); + let mut signature = result.signature; + let signature_capacity = signature.capacity(); + signature.reserve_exact(signature_capacity); + let result = SHAED25519DalekDigitalSignatureResult { + public_key: public_key.as_mut_ptr(), + public_key_length: public_key.len(), + signature_raw_ptr: signature.as_mut_ptr(), + signature_length: signature.len(), + }; + std::mem::forget(public_key); + std::mem::forget(signature); + result +} - let size_of_signature = std::mem::size_of_val(&signature_bytes); - let signature_raw_ptr = libc::malloc(size_of_signature) as *mut c_uchar; - std::ptr::copy_nonoverlapping( - signature_bytes.as_ptr(), - signature_raw_ptr, - size_of_signature, +#[no_mangle] +pub extern "C" fn sha512_ed25519_digital_signature_threadpool( + data_to_sign: *const c_uchar, + data_length: usize, +) -> SHAED25519DalekDigitalSignatureResult { + let data_to_sign_slice = unsafe { + assert!(!data_to_sign.is_null()); + std::slice::from_raw_parts(data_to_sign, data_length) + } + .to_vec(); + let result = + ::digital_signature_ed25519_threadpool( + data_to_sign_slice, ); - - let result = SHAED25519DalekDigitalSignatureResult { - public_key: public_key_raw_ptr, - public_key_length: size_of_public_key, - signature_raw_ptr: signature_raw_ptr, - signature_length: size_of_signature, - }; - result + let mut public_key = result.public_key; + let public_key_capacity = public_key.capacity(); + public_key.reserve_exact(public_key_capacity); + let mut signature = result.signature; + let signature_capacity = signature.capacity(); + signature.reserve_exact(signature_capacity); + let result = SHAED25519DalekDigitalSignatureResult { + public_key: public_key.as_mut_ptr(), + public_key_length: public_key.len(), + signature_raw_ptr: signature.as_mut_ptr(), + signature_length: signature.len(), }; + std::mem::forget(public_key); + std::mem::forget(signature); + result } #[no_mangle] @@ -251,44 +342,58 @@ pub extern "C" fn sha256_ed25519_digital_signature( let data_to_sign_slice = unsafe { assert!(!data_to_sign.is_null()); std::slice::from_raw_parts(data_to_sign, data_length) - }; - - let mut hasher = Sha3_256::new(); - hasher.update(data_to_sign_slice); - let sha_hasher_result = hasher.finalize(); - - let mut csprng = rand_07::rngs::OsRng {}; - let keypair = Keypair::generate(&mut csprng); - - let signature = keypair.sign(&sha_hasher_result); - let signature_bytes = signature.to_bytes(); - let public_keypair_bytes = keypair.public.to_bytes(); - - return unsafe { - let size_of_public_key = std::mem::size_of_val(&public_keypair_bytes); - let public_key_raw_ptr = libc::malloc(size_of_public_key) as *mut c_uchar; - std::ptr::copy_nonoverlapping( - public_keypair_bytes.as_ptr(), - public_key_raw_ptr, - size_of_public_key, + } + .to_vec(); + let result = + ::digital_signature_ed25519( + data_to_sign_slice, ); + let mut public_key = result.public_key; + let public_key_capacity = public_key.capacity(); + public_key.reserve_exact(public_key_capacity); + let mut signature = result.signature; + let signature_capacity = signature.capacity(); + signature.reserve_exact(signature_capacity); + let result = SHAED25519DalekDigitalSignatureResult { + public_key: public_key.as_mut_ptr(), + public_key_length: public_key.len(), + signature_raw_ptr: signature.as_mut_ptr(), + signature_length: signature.len(), + }; + std::mem::forget(public_key); + std::mem::forget(signature); + result +} - let size_of_signature = std::mem::size_of_val(&signature_bytes); - let signature_raw_ptr = libc::malloc(size_of_signature) as *mut c_uchar; - std::ptr::copy_nonoverlapping( - signature_bytes.as_ptr(), - signature_raw_ptr, - size_of_signature, +#[no_mangle] +pub extern "C" fn sha256_ed25519_digital_signature_threadpool( + data_to_sign: *const c_uchar, + data_length: usize, +) -> SHAED25519DalekDigitalSignatureResult { + let data_to_sign_slice = unsafe { + assert!(!data_to_sign.is_null()); + std::slice::from_raw_parts(data_to_sign, data_length) + } + .to_vec(); + let result = + ::digital_signature_ed25519_threadpool( + data_to_sign_slice, ); - - let result = SHAED25519DalekDigitalSignatureResult { - public_key: public_key_raw_ptr, - public_key_length: size_of_public_key, - signature_raw_ptr: signature_raw_ptr, - signature_length: size_of_signature, - }; - result + let mut public_key = result.public_key; + let public_key_capacity = public_key.capacity(); + public_key.reserve_exact(public_key_capacity); + let mut signature = result.signature; + let signature_capacity = signature.capacity(); + signature.reserve_exact(signature_capacity); + let result = SHAED25519DalekDigitalSignatureResult { + public_key: public_key.as_mut_ptr(), + public_key_length: public_key.len(), + signature_raw_ptr: signature.as_mut_ptr(), + signature_length: signature.len(), }; + std::mem::forget(public_key); + std::mem::forget(signature); + result } #[no_mangle] @@ -303,25 +408,48 @@ pub extern "C" fn sha512_ed25519_digital_signature_verify( let public_key_slice = unsafe { assert!(!public_key.is_null()); std::slice::from_raw_parts(public_key, public_key_length) - }; + } + .to_vec(); let data_to_verify_slice = unsafe { assert!(!data_to_verify.is_null()); std::slice::from_raw_parts(data_to_verify, data_to_verify_length) - }; + } + .to_vec(); let signature_slice = unsafe { assert!(!signature.is_null()); std::slice::from_raw_parts(signature, signature_length) - }; - - let mut hasher = Sha3_512::new(); - hasher.update(data_to_verify_slice); - let sha_hasher_result = hasher.finalize(); + } + .to_vec(); + let result = ::digital_signature_ed25519_verify(public_key_slice, data_to_verify_slice, signature_slice); + result +} - let public_key_parsed = ed25519_dalek::PublicKey::from_bytes(&public_key_slice).unwrap(); - let signature_parsed = Signature::from_bytes(&signature_slice).unwrap(); - return public_key_parsed - .verify(&sha_hasher_result, &signature_parsed) - .is_ok(); +#[no_mangle] +pub extern "C" fn sha512_ed25519_digital_signature_verify_threadpool( + public_key: *const c_uchar, + public_key_length: usize, + data_to_verify: *const c_uchar, + data_to_verify_length: usize, + signature: *const c_uchar, + signature_length: usize, +) -> bool { + let public_key_slice = unsafe { + assert!(!public_key.is_null()); + std::slice::from_raw_parts(public_key, public_key_length) + } + .to_vec(); + let data_to_verify_slice = unsafe { + assert!(!data_to_verify.is_null()); + std::slice::from_raw_parts(data_to_verify, data_to_verify_length) + } + .to_vec(); + let signature_slice = unsafe { + assert!(!signature.is_null()); + std::slice::from_raw_parts(signature, signature_length) + } + .to_vec(); + let result = ::digital_signature_ed25519_verify_threadpool(public_key_slice, data_to_verify_slice, signature_slice); + result } #[no_mangle] @@ -336,23 +464,46 @@ pub extern "C" fn sha256_ed25519_digital_signature_verify( let public_key_slice = unsafe { assert!(!public_key.is_null()); std::slice::from_raw_parts(public_key, public_key_length) - }; + } + .to_vec(); let data_to_verify_slice = unsafe { assert!(!data_to_verify.is_null()); std::slice::from_raw_parts(data_to_verify, data_to_verify_length) - }; + } + .to_vec(); let signature_slice = unsafe { assert!(!signature.is_null()); std::slice::from_raw_parts(signature, signature_length) - }; - - let mut hasher = Sha3_256::new(); - hasher.update(data_to_verify_slice); - let sha_hasher_result = hasher.finalize(); - - let public_key_parsed = ed25519_dalek::PublicKey::from_bytes(&public_key_slice).unwrap(); - let signature_parsed = Signature::from_bytes(&signature_slice).unwrap(); - return public_key_parsed - .verify(&sha_hasher_result, &signature_parsed) - .is_ok(); + } + .to_vec(); + let result = ::digital_signature_ed25519_verify(public_key_slice, data_to_verify_slice, signature_slice); + result } + +#[no_mangle] +pub extern "C" fn sha256_ed25519_digital_signature_verify_threadpool( + public_key: *const c_uchar, + public_key_length: usize, + data_to_verify: *const c_uchar, + data_to_verify_length: usize, + signature: *const c_uchar, + signature_length: usize, +) -> bool { + let public_key_slice = unsafe { + assert!(!public_key.is_null()); + std::slice::from_raw_parts(public_key, public_key_length) + } + .to_vec(); + let data_to_verify_slice = unsafe { + assert!(!data_to_verify.is_null()); + std::slice::from_raw_parts(data_to_verify, data_to_verify_length) + } + .to_vec(); + let signature_slice = unsafe { + assert!(!signature.is_null()); + std::slice::from_raw_parts(signature, signature_length) + } + .to_vec(); + let result = ::digital_signature_ed25519_verify_threadpool(public_key_slice, data_to_verify_slice, signature_slice); + result +} \ No newline at end of file diff --git a/src/ed25519.rs b/src/ed25519.rs index ed0b1bc..5625c33 100644 --- a/src/ed25519.rs +++ b/src/ed25519.rs @@ -1,10 +1,5 @@ -extern crate ed25519_dalek; -extern crate rand; - -use ed25519_dalek::Signer; -use ed25519_dalek::{Keypair, PublicKey, Signature, Verifier}; +use cas_lib::signatures::ed25519::{ed25519_sign_with_key_pair, ed25519_sign_with_key_pair_threadpool, ed25519_verify_with_key_pair, ed25519_verify_with_key_pair_threadpool, ed25519_verify_with_public_key, ed25519_verify_with_public_key_threadpool, get_ed25519_key_pair, get_ed25519_key_pair_threadpool}; use libc::c_uchar; -use rand_07::rngs::OsRng; #[repr(C)] pub struct Ed25519KeyPairBytesResult { @@ -22,21 +17,31 @@ pub struct Ed25519ByteSignatureResult { #[no_mangle] pub extern "C" fn get_ed25519_key_pair_bytes() -> Ed25519KeyPairBytesResult { - let mut csprng = OsRng {}; - let keypair = Keypair::generate(&mut csprng); - let keypair_bytes = keypair.to_bytes(); - return unsafe { - let size_of_result = std::mem::size_of_val(&keypair_bytes); - let result_raw_ptr = libc::malloc(size_of_result) as *mut c_uchar; - std::ptr::copy_nonoverlapping(keypair_bytes.as_ptr(), result_raw_ptr, size_of_result); - let result = Ed25519KeyPairBytesResult { - length: size_of_result, - key_pair: result_raw_ptr, - }; - result + let mut keypair = get_ed25519_key_pair(); + let capacity = keypair.capacity(); + keypair.reserve_exact(capacity); + let result = Ed25519KeyPairBytesResult { + length: keypair.len(), + key_pair: keypair.as_mut_ptr(), + }; + std::mem::forget(keypair); + result +} + +#[no_mangle] +pub extern "C" fn get_ed25519_key_pair_bytes_threadpool() -> Ed25519KeyPairBytesResult { + let mut keypair = get_ed25519_key_pair_threadpool(); + let capacity = keypair.capacity(); + keypair.reserve_exact(capacity); + let result = Ed25519KeyPairBytesResult { + length: keypair.len(), + key_pair: keypair.as_mut_ptr(), }; + std::mem::forget(keypair); + result } + #[test] fn get_ed25519_key_pair_bytes_test() { let key_pair_result = get_ed25519_key_pair_bytes(); @@ -54,38 +59,64 @@ pub extern "C" fn sign_with_key_pair_bytes( let key_pair_slice = unsafe { assert!(!key_pair.is_null()); std::slice::from_raw_parts(key_pair, key_pair_length) - }; + } + .to_vec(); let message_to_sign_slice = unsafe { assert!(!message_to_sign.is_null()); std::slice::from_raw_parts(message_to_sign, message_to_sign_length) + } + .to_vec(); + let result = ed25519_sign_with_key_pair(key_pair_slice, message_to_sign_slice); + let mut public_key = result.public_key; + let public_key_capacity = public_key.capacity(); + public_key.reserve_exact(public_key_capacity); + let mut signature = result.signature; + let siganture_capacity = signature.capacity(); + signature.reserve_exact(siganture_capacity); + let result = Ed25519ByteSignatureResult { + signature_byte_ptr: signature.as_mut_ptr(), + signature_length: signature.len(), + public_key: public_key.as_mut_ptr(), + public_key_length: public_key.len(), }; - let keypair = Keypair::from_bytes(key_pair_slice).unwrap(); - let signature = keypair.sign(&message_to_sign_slice); - let signature_bytes = signature.to_bytes(); - let public_keypair_bytes = keypair.public.to_bytes(); - return unsafe { - let size_of_signature = std::mem::size_of_val(&signature_bytes); - let signature_raw_ptr = libc::malloc(size_of_signature) as *mut c_uchar; - std::ptr::copy_nonoverlapping( - signature_bytes.as_ptr(), - signature_raw_ptr, - size_of_signature, - ); - let size_of_public_key = std::mem::size_of_val(&public_keypair_bytes); - let public_key_raw_ptr = libc::malloc(size_of_public_key) as *mut c_uchar; - std::ptr::copy_nonoverlapping( - public_keypair_bytes.as_ptr(), - public_key_raw_ptr, - size_of_public_key, - ); - let result = Ed25519ByteSignatureResult { - signature_byte_ptr: signature_raw_ptr, - signature_length: size_of_signature, - public_key: public_key_raw_ptr, - public_key_length: size_of_public_key, - }; - result + std::mem::forget(public_key); + std::mem::forget(signature); + result +} + +#[no_mangle] +pub extern "C" fn sign_with_key_pair_bytes_threadpool( + key_pair: *const c_uchar, + key_pair_length: usize, + message_to_sign: *const c_uchar, + message_to_sign_length: usize, +) -> Ed25519ByteSignatureResult { + let key_pair_slice = unsafe { + assert!(!key_pair.is_null()); + std::slice::from_raw_parts(key_pair, key_pair_length) + } + .to_vec(); + let message_to_sign_slice = unsafe { + assert!(!message_to_sign.is_null()); + std::slice::from_raw_parts(message_to_sign, message_to_sign_length) + } + .to_vec(); + let result = ed25519_sign_with_key_pair_threadpool(key_pair_slice, message_to_sign_slice); + let mut public_key = result.public_key; + let public_key_capacity = public_key.capacity(); + public_key.reserve_exact(public_key_capacity); + let mut signature = result.signature; + let siganture_capacity = signature.capacity(); + signature.reserve_exact(siganture_capacity); + let result = Ed25519ByteSignatureResult { + signature_byte_ptr: signature.as_mut_ptr(), + signature_length: signature.len(), + public_key: public_key.as_mut_ptr(), + public_key_length: public_key.len(), }; + std::mem::forget(public_key); + std::mem::forget(signature); + result } #[test] @@ -117,19 +148,40 @@ pub extern "C" fn verify_with_key_pair_bytes( let key_pair_slice = unsafe { assert!(!key_pair.is_null()); std::slice::from_raw_parts(key_pair, key_pair_length) - }; + }.to_vec(); let signature_slice = unsafe { assert!(!signature.is_null()); std::slice::from_raw_parts(signature, signature_length) - }; + }.to_vec(); let message_slice = unsafe { assert!(!message.is_null()); std::slice::from_raw_parts(message, message_length) - }; - let keypair = Keypair::from_bytes(&key_pair_slice).unwrap(); - let public_key = keypair.public; - let signature = Signature::from_bytes(&signature_slice).unwrap(); - return public_key.verify(&message_slice, &signature).is_ok(); + }.to_vec(); + return ed25519_verify_with_key_pair(key_pair_slice, signature_slice, message_slice); +} + +#[no_mangle] +pub extern "C" fn verify_with_key_pair_bytes_threadpool( + key_pair: *const c_uchar, + key_pair_length: usize, + signature: *const c_uchar, + signature_length: usize, + message: *const c_uchar, + message_length: usize, +) -> bool { + let key_pair_slice = unsafe { + assert!(!key_pair.is_null()); + std::slice::from_raw_parts(key_pair, key_pair_length) + }.to_vec(); + let signature_slice = unsafe { + assert!(!signature.is_null()); + std::slice::from_raw_parts(signature, signature_length) + }.to_vec(); + let message_slice = unsafe { + assert!(!message.is_null()); + std::slice::from_raw_parts(message, message_length) + }.to_vec(); + return ed25519_verify_with_key_pair_threadpool(key_pair_slice, signature_slice, message_slice); } #[test] @@ -165,20 +217,40 @@ pub extern "C" fn verify_with_public_key_bytes( let public_key_slice = unsafe { assert!(!public_key.is_null()); std::slice::from_raw_parts(public_key, public_key_length) - }; + }.to_vec(); let signature_slice = unsafe { assert!(!signature.is_null()); std::slice::from_raw_parts(signature, signature_length) - }; + }.to_vec(); let message_slice = unsafe { assert!(!message.is_null()); std::slice::from_raw_parts(message, message_length) - }; - let public_key_parsed = PublicKey::from_bytes(&public_key_slice).unwrap(); - let signature_parsed = Signature::from_bytes(&signature_slice).unwrap(); - return public_key_parsed - .verify(&message_slice, &signature_parsed) - .is_ok(); + }.to_vec(); + return ed25519_verify_with_public_key(public_key_slice, signature_slice, message_slice); +} + +#[no_mangle] +pub extern "C" fn verify_with_public_key_bytes_threadpool( + public_key: *const c_uchar, + public_key_length: usize, + signature: *const c_uchar, + signature_length: usize, + message: *const c_uchar, + message_length: usize, +) -> bool { + let public_key_slice = unsafe { + assert!(!public_key.is_null()); + std::slice::from_raw_parts(public_key, public_key_length) + }.to_vec(); + let signature_slice = unsafe { + assert!(!signature.is_null()); + std::slice::from_raw_parts(signature, signature_length) + }.to_vec(); + let message_slice = unsafe { + assert!(!message.is_null()); + std::slice::from_raw_parts(message, message_length) + }.to_vec(); + return ed25519_verify_with_public_key_threadpool(public_key_slice, signature_slice, message_slice); } #[test] diff --git a/src/hmac.rs b/src/hmac.rs deleted file mode 100644 index 837a279..0000000 --- a/src/hmac.rs +++ /dev/null @@ -1,99 +0,0 @@ -use hmac::{Hmac, Mac}; -use libc::c_uchar; -use sha2::Sha256; - -type HmacSha256 = Hmac; - -#[repr(C)] -pub struct HmacSignByteResult { - pub result_bytes_ptr: *mut c_uchar, - pub length: usize, -} - -#[no_mangle] -pub extern "C" fn hmac_sign_bytes( - key: *const c_uchar, - key_length: usize, - message: *const c_uchar, - message_length: usize, -) -> HmacSignByteResult { - assert!(!key.is_null()); - assert!(!message.is_null()); - let key_slice: &[u8] = unsafe { std::slice::from_raw_parts(key, key_length) }; - let message_slice: &[u8] = unsafe { std::slice::from_raw_parts(message, message_length) }; - let mut mac = HmacSha256::new_from_slice(key_slice).unwrap(); - mac.update(message_slice); - let result = mac.finalize().into_bytes(); - return unsafe { - let size_of_result = std::mem::size_of_val(&result); - let result_raw_ptr = libc::malloc(size_of_result) as *mut c_uchar; - std::ptr::copy_nonoverlapping(result.as_ptr(), result_raw_ptr, size_of_result); - let result = HmacSignByteResult { - result_bytes_ptr: result_raw_ptr, - length: size_of_result, - }; - result - }; -} - -#[test] -fn hmac_sign_bytes_test() { - let data_to_sign = "Bad Hmac Test"; - let data_to_sign_bytes: &[u8] = data_to_sign.as_bytes(); - let data_to_sign_length: usize = data_to_sign_bytes.len(); - let hmac_key = "ThisIsAHmacKeyBadNewsBears"; - let hmac_key_bytes = hmac_key.as_bytes(); - let hmac_key_bytes_length = hmac_key_bytes.len(); - let result: HmacSignByteResult = hmac_sign_bytes( - hmac_key_bytes.as_ptr(), - hmac_key_bytes_length, - data_to_sign_bytes.as_ptr(), - data_to_sign_length, - ); - assert_ne!(data_to_sign_bytes.as_ptr(), result.result_bytes_ptr); -} - -#[no_mangle] -pub extern "C" fn hmac_verify_bytes( - key: *const c_uchar, - key_length: usize, - message: *const c_uchar, - message_length: usize, - signature: *const c_uchar, - signature_length: usize, -) -> bool { - assert!(!key.is_null()); - assert!(!message.is_null()); - assert!(!signature.is_null()); - let key_slice: &[u8] = unsafe { std::slice::from_raw_parts(key, key_length) }; - let message_slice: &[u8] = unsafe { std::slice::from_raw_parts(message, message_length) }; - let signature_slice: &[u8] = unsafe { std::slice::from_raw_parts(signature, signature_length) }; - let mut mac = HmacSha256::new_from_slice(key_slice).unwrap(); - mac.update(message_slice); - return mac.verify_slice(signature_slice).is_ok(); -} - -#[test] -fn hmac_verify_bytes_test() { - let data_to_sign = "Bad Hmac Test 1234567890"; - let data_to_sign_bytes: &[u8] = data_to_sign.as_bytes(); - let data_to_sign_length: usize = data_to_sign_bytes.len(); - let hmac_key = "ThisIsAHmacKeyBadNewsBears"; - let hmac_key_bytes = hmac_key.as_bytes(); - let hmac_key_bytes_length = hmac_key_bytes.len(); - let result: HmacSignByteResult = hmac_sign_bytes( - hmac_key_bytes.as_ptr(), - hmac_key_bytes_length, - data_to_sign_bytes.as_ptr(), - data_to_sign_length, - ); - let valid = hmac_verify_bytes( - hmac_key_bytes.as_ptr(), - hmac_key_bytes_length, - data_to_sign_bytes.as_ptr(), - data_to_sign_length, - result.result_bytes_ptr, - result.length, - ); - assert_eq!(true, valid); -} diff --git a/src/hmac/mod.rs b/src/hmac/mod.rs new file mode 100644 index 0000000..711804a --- /dev/null +++ b/src/hmac/mod.rs @@ -0,0 +1,132 @@ +use cas_lib::message::{cas_hmac::CASHMAC, hmac::HMAC}; +use libc::c_uchar; + +use self::types::HmacSignByteResult; + +mod types; + +#[no_mangle] +pub extern "C" fn hmac_sign_bytes( + key: *const c_uchar, + key_length: usize, + message: *const c_uchar, + message_length: usize, +) -> HmacSignByteResult { + assert!(!key.is_null()); + assert!(!message.is_null()); + let key_slice: Vec = unsafe { std::slice::from_raw_parts(key, key_length) }.to_vec(); + let message_slice: Vec = + unsafe { std::slice::from_raw_parts(message, message_length) }.to_vec(); + let mut result = ::sign(key_slice, message_slice); + let capacity = result.capacity(); + result.reserve_exact(capacity); + let return_result = HmacSignByteResult { + result_bytes_ptr: result.as_mut_ptr(), + length: result.len(), + }; + std::mem::forget(result); + return_result +} + +#[no_mangle] +pub extern "C" fn hmac_sign_bytes_threadpool( + key: *const c_uchar, + key_length: usize, + message: *const c_uchar, + message_length: usize, +) -> HmacSignByteResult { + assert!(!key.is_null()); + assert!(!message.is_null()); + let key_slice: Vec = unsafe { std::slice::from_raw_parts(key, key_length) }.to_vec(); + let message_slice: Vec = + unsafe { std::slice::from_raw_parts(message, message_length) }.to_vec(); + let mut result = ::sign_threadpool(key_slice, message_slice); + let capacity = result.capacity(); + result.reserve_exact(capacity); + let return_result = HmacSignByteResult { + result_bytes_ptr: result.as_mut_ptr(), + length: result.len(), + }; + std::mem::forget(result); + return_result +} + +#[test] +fn hmac_sign_bytes_test() { + let data_to_sign = "Bad Hmac Test"; + let data_to_sign_bytes: &[u8] = data_to_sign.as_bytes(); + let data_to_sign_length: usize = data_to_sign_bytes.len(); + let hmac_key = "ThisIsAHmacKeyBadNewsBears"; + let hmac_key_bytes = hmac_key.as_bytes(); + let hmac_key_bytes_length = hmac_key_bytes.len(); + let result: HmacSignByteResult = hmac_sign_bytes( + hmac_key_bytes.as_ptr(), + hmac_key_bytes_length, + data_to_sign_bytes.as_ptr(), + data_to_sign_length, + ); + assert_ne!(data_to_sign_bytes.as_ptr(), result.result_bytes_ptr); +} + +#[no_mangle] +pub extern "C" fn hmac_verify_bytes( + key: *const c_uchar, + key_length: usize, + message: *const c_uchar, + message_length: usize, + signature: *const c_uchar, + signature_length: usize, +) -> bool { + assert!(!key.is_null()); + assert!(!message.is_null()); + assert!(!signature.is_null()); + let key_slice: Vec = unsafe { std::slice::from_raw_parts(key, key_length) }.to_vec(); + let message_slice: Vec = unsafe { std::slice::from_raw_parts(message, message_length) }.to_vec(); + let signature_slice: Vec = unsafe { std::slice::from_raw_parts(signature, signature_length) }.to_vec(); + let result = ::verify(key_slice, message_slice, signature_slice); + result +} + +#[no_mangle] +pub extern "C" fn hmac_verify_bytes_threadpool( + key: *const c_uchar, + key_length: usize, + message: *const c_uchar, + message_length: usize, + signature: *const c_uchar, + signature_length: usize, +) -> bool { + assert!(!key.is_null()); + assert!(!message.is_null()); + assert!(!signature.is_null()); + let key_slice: Vec = unsafe { std::slice::from_raw_parts(key, key_length) }.to_vec(); + let message_slice: Vec = unsafe { std::slice::from_raw_parts(message, message_length) }.to_vec(); + let signature_slice: Vec = unsafe { std::slice::from_raw_parts(signature, signature_length) }.to_vec(); + let result = ::verify_threadpool(key_slice, message_slice, signature_slice); + result +} + +#[test] +fn hmac_verify_bytes_test() { + let data_to_sign = "Bad Hmac Test 1234567890"; + let data_to_sign_bytes: &[u8] = data_to_sign.as_bytes(); + let data_to_sign_length: usize = data_to_sign_bytes.len(); + let hmac_key = "ThisIsAHmacKeyBadNewsBears"; + let hmac_key_bytes = hmac_key.as_bytes(); + let hmac_key_bytes_length = hmac_key_bytes.len(); + let result: HmacSignByteResult = hmac_sign_bytes( + hmac_key_bytes.as_ptr(), + hmac_key_bytes_length, + data_to_sign_bytes.as_ptr(), + data_to_sign_length, + ); + let valid = hmac_verify_bytes( + hmac_key_bytes.as_ptr(), + hmac_key_bytes_length, + data_to_sign_bytes.as_ptr(), + data_to_sign_length, + result.result_bytes_ptr, + result.length, + ); + assert_eq!(true, valid); +} diff --git a/src/hmac/types.rs b/src/hmac/types.rs new file mode 100644 index 0000000..de6cc23 --- /dev/null +++ b/src/hmac/types.rs @@ -0,0 +1,7 @@ +use std::ffi::c_uchar; + +#[repr(C)] +pub struct HmacSignByteResult { + pub result_bytes_ptr: *mut c_uchar, + pub length: usize, +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index a2f17d4..5c7d3a2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,16 @@ -// Password Hashes mod aes; -mod argon2; -mod bcrypt; mod blake2; mod digital_signature; mod ed25519; mod helpers; mod hmac; mod rsa; -mod scrypt; mod sha; mod x25519; -mod ascon_aead; \ No newline at end of file +mod ascon_aead; + +pub mod password_hashers { + pub mod argon2; + pub mod scrypt; + pub mod bcrypt; +} \ No newline at end of file diff --git a/src/argon2.rs b/src/password_hashers/argon2.rs similarity index 73% rename from src/argon2.rs rename to src/password_hashers/argon2.rs index 2774989..2541f0c 100644 --- a/src/argon2.rs +++ b/src/password_hashers/argon2.rs @@ -1,33 +1,24 @@ -use std::{ - ffi::{c_char, CStr, CString}, sync::mpsc -}; -use argon2::{ - password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString}, - Argon2, -}; +use std::ffi::{c_char, CStr, CString}; +use cas_lib::password_hashers::{argon2::CASArgon, cas_password_hasher::CASPasswordHasher}; #[no_mangle] pub extern "C" fn argon2_verify(hashed_pass: *const c_char, password: *const c_char) -> bool { - let hashed_pass_string = unsafe { + let hashed_password = unsafe { assert!(!hashed_pass.is_null()); CStr::from_ptr(hashed_pass) } .to_str() - .unwrap(); + .unwrap() + .to_string(); - let password_string = unsafe { + let password_to_verify = unsafe { assert!(!password.is_null()); CStr::from_ptr(password) } .to_str() .unwrap() - .as_bytes(); - - let parsed_hash = PasswordHash::new(&hashed_pass_string).unwrap(); - let result = Argon2::default() - .verify_password(password_string, &parsed_hash) - .is_ok(); - return result; + .to_string(); + return ::verify_password(hashed_password, password_to_verify); } #[test] @@ -69,7 +60,8 @@ pub extern "C" fn argon2_verify_threadpool(hashed_pass: *const c_char, password: CStr::from_ptr(hashed_pass) } .to_str() - .unwrap(); + .unwrap() + .to_string(); let password_string = unsafe { assert!(!password.is_null()); @@ -77,16 +69,8 @@ pub extern "C" fn argon2_verify_threadpool(hashed_pass: *const c_char, password: } .to_str() .unwrap() - .as_bytes(); - let (sender, receiver) = mpsc::channel(); - rayon::spawn(move || { - let parsed_hash = PasswordHash::new(&hashed_pass_string).unwrap(); - let thread_result = Argon2::default() - .verify_password(password_string, &parsed_hash) - .is_ok(); - sender.send(thread_result); - }); - let result = receiver.recv().unwrap(); + .to_string(); + let result: bool = ::verify_password_threadpool(hashed_pass_string, password_string); result } @@ -106,18 +90,15 @@ fn argon2_verify_threadpool_test() { #[no_mangle] pub extern "C" fn argon2_hash(pass_to_hash: *const c_char) -> *mut c_char { - let pass_bytes = unsafe { + let password = unsafe { assert!(!pass_to_hash.is_null()); CStr::from_ptr(pass_to_hash) } .to_str() .unwrap() - .as_bytes(); - let salt = SaltString::generate(&mut OsRng); - let argon2 = Argon2::default(); - let password_hash = CString::new(argon2.hash_password(pass_bytes, &salt).unwrap().to_string()) - .unwrap() - .into_raw(); + .to_string(); + let new_hash = ::hash_password(password); + let password_hash = CString::new(new_hash).unwrap().into_raw(); return password_hash; } @@ -135,21 +116,15 @@ fn argon2_hash_test() { #[no_mangle] pub extern "C" fn argon2_hash_threadpool(pass_to_hash: *const c_char) -> *mut c_char { - let pass_bytes = unsafe { + let password = unsafe { assert!(!pass_to_hash.is_null()); CStr::from_ptr(pass_to_hash) } .to_str() .unwrap() - .as_bytes(); - let (sender, receiver) = mpsc::channel(); - rayon::spawn(move || { - let salt = SaltString::generate(&mut OsRng); - let argon2 = Argon2::default(); - let password_hash = argon2.hash_password(pass_bytes, &salt).unwrap().to_string(); - sender.send(password_hash); - }); - let result = CString::new(receiver.recv().unwrap()).unwrap().into_raw(); + .to_string(); + let new_hash = ::hash__password_threadpool(password); + let result = CString::new(new_hash).unwrap().into_raw(); result } diff --git a/src/bcrypt.rs b/src/password_hashers/bcrypt.rs similarity index 80% rename from src/bcrypt.rs rename to src/password_hashers/bcrypt.rs index def6296..2badb80 100644 --- a/src/bcrypt.rs +++ b/src/password_hashers/bcrypt.rs @@ -1,8 +1,7 @@ use std::{ ffi::{c_char, CStr, CString}, sync::mpsc, thread }; - -use bcrypt::{hash, verify, DEFAULT_COST}; +use cas_lib::password_hashers::{bcrypt::CASBCrypt, cas_password_hasher::CASPasswordHasher}; #[no_mangle] pub extern "C" fn bcrypt_hash(pass_to_hash: *const c_char) -> *mut c_char { @@ -12,10 +11,10 @@ pub extern "C" fn bcrypt_hash(pass_to_hash: *const c_char) -> *mut c_char { CStr::from_ptr(pass_to_hash) } .to_str() - .unwrap(); - - let hashed_password = CString::new(hash(string_pass, DEFAULT_COST).unwrap()).unwrap(); - return hashed_password.into_raw(); + .unwrap() + .to_string(); + let new_hashed = ::hash_password(string_pass); + return CString::new(new_hashed).unwrap().into_raw(); } #[test] @@ -38,14 +37,10 @@ pub extern "C" fn bcrypt_hash_threadpool(pass_to_hash: *const c_char) -> *mut c_ CStr::from_ptr(pass_to_hash) } .to_str() - .unwrap(); - let (sender, receiver) = mpsc::channel(); - rayon::spawn(move || { - let hashed_password = hash(string_pass, DEFAULT_COST).unwrap(); - sender.send(hashed_password); - }); - let result = CString::new(receiver.recv().unwrap()).unwrap().into_raw(); - result + .unwrap() + .to_string(); + let new_hash = ::hash__password_threadpool(string_pass); + return CString::new(new_hash).unwrap().into_raw(); } #[test] @@ -68,7 +63,8 @@ pub extern "C" fn bcrypt_verify(pass: *const c_char, hash: *const c_char) -> boo CStr::from_ptr(pass) } .to_str() - .unwrap(); + .unwrap() + .to_string(); let string_hash = unsafe { assert!(!hash.is_null()); @@ -76,8 +72,9 @@ pub extern "C" fn bcrypt_verify(pass: *const c_char, hash: *const c_char) -> boo CStr::from_ptr(hash) } .to_str() - .unwrap(); - return verify(string_pass, string_hash).unwrap(); + .unwrap() + .to_string(); + return ::verify_password(string_hash, string_pass); } #[test] @@ -102,7 +99,8 @@ pub extern "C" fn bcrypt_verify_threadpool(pass: *const c_char, hash: *const c_c CStr::from_ptr(pass) } .to_str() - .unwrap(); + .unwrap() + .to_string(); let string_hash = unsafe { assert!(!hash.is_null()); @@ -110,14 +108,9 @@ pub extern "C" fn bcrypt_verify_threadpool(pass: *const c_char, hash: *const c_c CStr::from_ptr(hash) } .to_str() - .unwrap(); - let (sender, receiver) = mpsc::channel(); - rayon::spawn(move || { - let thread_result = verify(string_pass, string_hash).unwrap(); - sender.send(thread_result); - }); - let result = receiver.recv().unwrap(); - result + .unwrap() + .to_string(); + return ::verify_password(string_hash, string_pass); } #[test] diff --git a/src/scrypt.rs b/src/password_hashers/scrypt.rs similarity index 70% rename from src/scrypt.rs rename to src/password_hashers/scrypt.rs index a0cd509..30b9443 100644 --- a/src/scrypt.rs +++ b/src/password_hashers/scrypt.rs @@ -1,9 +1,5 @@ -use std::{ffi::{c_char, CStr, CString}, sync::mpsc}; - -use scrypt::{ - password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString}, - Scrypt, -}; +use std::ffi::{c_char, CStr, CString}; +use cas_lib::password_hashers::{cas_password_hasher::CASPasswordHasher, scrypt::CASScrypt}; #[no_mangle] pub extern "C" fn scrypt_hash(pass_to_hash: *const c_char) -> *mut c_char { @@ -13,14 +9,10 @@ pub extern "C" fn scrypt_hash(pass_to_hash: *const c_char) -> *mut c_char { CStr::from_ptr(pass_to_hash) } .to_str() - .unwrap(); - - let salt = SaltString::generate(&mut OsRng); - let hashed = Scrypt - .hash_password(string_pass.as_bytes(), &salt) - .unwrap() - .to_string(); - return CString::new(hashed).unwrap().into_raw(); + .unwrap() + .to_string(); + let new_hash = ::hash_password(string_pass); + return CString::new(new_hash).unwrap().into_raw(); } #[test] @@ -43,18 +35,10 @@ pub extern "C" fn scrypt_hash_threadpool(pass_to_hash: *const c_char) -> *mut c_ CStr::from_ptr(pass_to_hash) } .to_str() - .unwrap(); - let (sender, receiver) = mpsc::channel(); - rayon::spawn(move || { - let salt = SaltString::generate(&mut OsRng); - let hashed = Scrypt - .hash_password(string_pass.as_bytes(), &salt) - .unwrap() - .to_string(); - sender.send(hashed); - }); - let result = CString::new(receiver.recv().unwrap()).unwrap().into_raw(); - result + .unwrap() + .to_string(); + let new_hash = ::hash__password_threadpool(string_pass); + return CString::new(new_hash).unwrap().into_raw(); } #[test] @@ -80,7 +64,8 @@ pub extern "C" fn scrypt_verify( CStr::from_ptr(pass_to_check) } .to_str() - .unwrap(); + .unwrap() + .to_string(); let string_hash = unsafe { assert!(!hash_to_check.is_null()); @@ -88,12 +73,10 @@ pub extern "C" fn scrypt_verify( CStr::from_ptr(hash_to_check) } .to_str() - .unwrap(); + .unwrap() + .to_string(); - let parsed_hash = PasswordHash::new(&string_hash).unwrap(); - return Scrypt - .verify_password(string_pass.as_bytes(), &parsed_hash) - .is_ok(); + return ::verify_password(string_hash, string_pass); } #[test] @@ -121,7 +104,8 @@ pub extern "C" fn scrypt_verify_threadpool( CStr::from_ptr(pass_to_check) } .to_str() - .unwrap(); + .unwrap() + .to_string(); let string_hash = unsafe { assert!(!hash_to_check.is_null()); @@ -129,17 +113,10 @@ pub extern "C" fn scrypt_verify_threadpool( CStr::from_ptr(hash_to_check) } .to_str() - .unwrap(); - let (sender, receiver) = mpsc::channel(); - rayon::spawn(move || { - let parsed_hash = PasswordHash::new(&string_hash).unwrap(); - let thread_result = Scrypt - .verify_password(string_pass.as_bytes(), &parsed_hash) - .is_ok(); - sender.send(thread_result); - }); - let result = receiver.recv().unwrap(); - result + .unwrap() + .to_string(); + + return ::verify_password(string_hash, string_pass); } #[test] diff --git a/src/rsa.rs b/src/rsa.rs deleted file mode 100644 index 257fdbc..0000000 --- a/src/rsa.rs +++ /dev/null @@ -1,286 +0,0 @@ -use std::ffi::{c_char, c_uchar, CStr, CString}; - -use rand::rngs::OsRng; -use rsa::RsaPrivateKey; -use rsa::{ - pkcs1::{DecodeRsaPublicKey, EncodeRsaPublicKey}, - pkcs8::{DecodePrivateKey, EncodePrivateKey}, - PaddingScheme, PublicKey, RsaPublicKey, -}; - -#[repr(C)] -pub struct RsaKeyPair { - pub pub_key: *mut c_char, - pub priv_key: *mut c_char, -} - -#[repr(C)] -pub struct RsaSignBytesResults { - pub signature_raw_ptr: *mut c_uchar, - pub length: usize, -} - -#[repr(C)] -pub struct RsaEncryptBytesResult { - pub encrypted_result_ptr: *mut c_uchar, - pub length: usize, -} - -#[repr(C)] -pub struct RsaDecryptBytesResult { - pub decrypted_result_ptr: *mut c_uchar, - pub length: usize, -} - -#[no_mangle] -pub extern "C" fn rsa_encrypt( - pub_key: *const c_char, - data_to_encrypt: *const c_char, -) -> *mut c_char { - let pub_key_string = unsafe { - assert!(!pub_key.is_null()); - - CStr::from_ptr(pub_key) - } - .to_str() - .unwrap(); - - let data_to_encrypt_bytes = unsafe { - assert!(!data_to_encrypt.is_null()); - - CStr::from_ptr(data_to_encrypt) - } - .to_str() - .unwrap() - .as_bytes(); - - let public_key = RsaPublicKey::from_pkcs1_pem(pub_key_string).unwrap(); - let mut rng = rand::thread_rng(); - let encrypted_bytes = public_key - .encrypt( - &mut rng, - PaddingScheme::new_pkcs1v15_encrypt(), - &data_to_encrypt_bytes, - ) - .unwrap(); - return CString::new(base64::encode(encrypted_bytes)) - .unwrap() - .into_raw(); -} - -#[no_mangle] -pub extern "C" fn rsa_encrypt_bytes( - pub_key: *const c_char, - data_to_encrypt: *const c_uchar, - data_to_encrypt_length: usize, -) -> RsaEncryptBytesResult { - let pub_key_string = unsafe { - assert!(!pub_key.is_null()); - CStr::from_ptr(pub_key) - } - .to_str() - .unwrap(); - let data_to_encrypt_slice = unsafe { - assert!(!data_to_encrypt.is_null()); - std::slice::from_raw_parts(data_to_encrypt, data_to_encrypt_length) - }; - let public_key = RsaPublicKey::from_pkcs1_pem(pub_key_string).unwrap(); - let mut rng = rand::thread_rng(); - let mut encrypted_bytes = public_key - .encrypt( - &mut rng, - PaddingScheme::new_pkcs1v15_encrypt(), - data_to_encrypt_slice, - ) - .unwrap(); - let capacity = encrypted_bytes.capacity(); - encrypted_bytes.reserve_exact(capacity); - let result = RsaEncryptBytesResult { - encrypted_result_ptr: encrypted_bytes.as_mut_ptr(), - length: encrypted_bytes.len(), - }; - std::mem::forget(encrypted_bytes); - return result; -} - -#[test] -fn rsa_encrypt_test() { - let keys = get_key_pair(4096); - let public_key_cstr = unsafe { CString::from_raw(keys.pub_key) }; - let public_key_ptr = public_key_cstr.as_bytes_with_nul().as_ptr() as *const i8; - - let password = "DontUseThisPassword"; - let password_cstr = CString::new(password).unwrap(); - let password_bytes = password_cstr.as_bytes_with_nul(); - let password_ptr = password_bytes.as_ptr() as *const i8; - - let encrypted = rsa_encrypt(public_key_ptr, password_ptr); - let encrypted_cstr = unsafe { CString::from_raw(encrypted) }; - let encrypted_str = encrypted_cstr.to_str().unwrap(); - assert_ne!(password, encrypted_str); -} - -#[no_mangle] -pub extern "C" fn rsa_decrypt_bytes( - priv_key: *const c_char, - data_to_decrypt: *const c_uchar, - data_to_decrypt_length: usize, -) -> RsaDecryptBytesResult { - let priv_key_string = unsafe { - assert!(!priv_key.is_null()); - CStr::from_ptr(priv_key) - } - .to_str() - .unwrap(); - - let data_to_decrypt_slice: &[u8] = unsafe { - assert!(!data_to_decrypt.is_null()); - std::slice::from_raw_parts(data_to_decrypt, data_to_decrypt_length) - }; - - let private_key = RsaPrivateKey::from_pkcs8_pem(priv_key_string).unwrap(); - let mut decrypted_bytes = private_key - .decrypt( - PaddingScheme::new_pkcs1v15_encrypt(), - &data_to_decrypt_slice, - ) - .expect("failed to decrypt"); - let capacity = decrypted_bytes.capacity(); - decrypted_bytes.reserve_exact(capacity); - let result = RsaDecryptBytesResult { - decrypted_result_ptr: decrypted_bytes.as_mut_ptr(), - length: decrypted_bytes.len(), - }; - std::mem::forget(decrypted_bytes); - return result; -} - -#[no_mangle] -pub extern "C" fn get_key_pair(key_size: usize) -> RsaKeyPair { - let mut rng: OsRng = OsRng; - let private_key: RsaPrivateKey = - RsaPrivateKey::new(&mut rng, key_size).expect("failed to generate a key"); - let public_key: RsaPublicKey = private_key.to_public_key(); - let key_pair = RsaKeyPair { - pub_key: CString::new( - public_key - .to_pkcs1_pem(rsa::pkcs1::LineEnding::LF) - .unwrap() - .to_string(), - ) - .unwrap() - .into_raw(), - priv_key: CString::new( - private_key - .to_pkcs8_pem(rsa::pkcs8::LineEnding::LF) - .unwrap() - .to_string(), - ) - .unwrap() - .into_raw(), - }; - return key_pair; -} - -#[no_mangle] -pub extern "C" fn rsa_sign_with_key_bytes( - private_key: *const c_char, - data_to_sign: *const c_uchar, - data_to_sign_length: usize, -) -> RsaSignBytesResults { - let private_key_string = unsafe { - assert!(!private_key.is_null()); - - CStr::from_ptr(private_key) - } - .to_str() - .unwrap(); - let data_to_sign_slice: &[u8] = unsafe { - assert!(!data_to_sign.is_null()); - std::slice::from_raw_parts(data_to_sign, data_to_sign_length) - }; - let private_key = - RsaPrivateKey::from_pkcs8_pem(private_key_string).expect("failed to generate a key"); - let mut signed_data = private_key - .sign(PaddingScheme::new_pkcs1v15_sign_raw(), data_to_sign_slice) - .unwrap(); - let capacity = signed_data.capacity(); - signed_data.reserve_exact(capacity); - let result = RsaSignBytesResults { - signature_raw_ptr: signed_data.as_mut_ptr(), - length: signed_data.len(), - }; - std::mem::forget(signed_data); - return result; -} - -#[test] -fn rsa_sign_nonffi_test() { - let mut rng: OsRng = OsRng; - let private_key: RsaPrivateKey = - RsaPrivateKey::new(&mut rng, 2094).expect("failed to generate a key"); - let public_key: RsaPublicKey = private_key.to_public_key(); - let data = b"testing"; - let signature = private_key - .sign(PaddingScheme::new_pkcs1v15_sign_raw(), data) - .unwrap(); - assert_ne!(data.as_slice(), signature); -} - -#[no_mangle] -pub extern "C" fn rsa_verify_bytes( - public_key: *const c_char, - data_to_verify: *const c_uchar, - data_to_verify_length: usize, - signature: *const c_uchar, - signature_length: usize, -) -> bool { - let public_key_string = unsafe { - assert!(!public_key.is_null()); - - CStr::from_ptr(public_key) - } - .to_str() - .unwrap(); - let data_to_verify_slice: &[u8] = unsafe { - assert!(!data_to_verify.is_null()); - std::slice::from_raw_parts(data_to_verify, data_to_verify_length) - }; - let signature_slice: &[u8] = unsafe { - assert!(!signature.is_null()); - std::slice::from_raw_parts(signature, signature_length) - }; - let public_key = RsaPublicKey::from_pkcs1_pem(public_key_string).unwrap(); - let verified = public_key.verify( - PaddingScheme::new_pkcs1v15_sign_raw(), - &data_to_verify_slice, - &signature_slice, - ); - if verified.is_err() == false { - return true; - } else { - return false; - } -} - -#[test] -fn rsa_verify_nonffi_test() { - let mut rng: OsRng = OsRng; - let private_key: RsaPrivateKey = - RsaPrivateKey::new(&mut rng, 2094).expect("failed to generate a key"); - let public_key: RsaPublicKey = private_key.to_public_key(); - let data = "testing".as_bytes(); - let signature = private_key - .sign(PaddingScheme::new_pkcs1v15_sign_raw(), data) - .unwrap(); - let verified = public_key.verify(PaddingScheme::new_pkcs1v15_sign_raw(), &data, &signature); - assert_eq!(verified.is_err(), false); -} - -#[test] -fn get_key_pair_test() { - let key_size = 4096 as usize; - let key_pair = get_key_pair(key_size); - assert!(!key_pair.pub_key.is_null()); - assert!(!key_pair.priv_key.is_null()); -} diff --git a/src/rsa/mod.rs b/src/rsa/mod.rs new file mode 100644 index 0000000..14895cf --- /dev/null +++ b/src/rsa/mod.rs @@ -0,0 +1,276 @@ +use std::ffi::{c_char, c_uchar, CStr, CString}; + +use cas_lib::asymmetric::cas_asymmetric_encryption::CASRSAEncryption; +use cas_lib::asymmetric::cas_rsa::CASRSA; +use cas_lib::asymmetric::types::RSAKeyPairResult; + +mod types; +use self::types::{RsaDecryptBytesResult, RsaEncryptBytesResult, RsaKeyPair, RsaSignBytesResults}; + +#[no_mangle] +pub extern "C" fn rsa_encrypt_bytes( + pub_key: *const c_char, + data_to_encrypt: *const c_uchar, + data_to_encrypt_length: usize, +) -> RsaEncryptBytesResult { + let pub_key_string = unsafe { + assert!(!pub_key.is_null()); + CStr::from_ptr(pub_key) + } + .to_str() + .unwrap() + .to_string(); + + let data_to_encrypt_slice = unsafe { + assert!(!data_to_encrypt.is_null()); + std::slice::from_raw_parts(data_to_encrypt, data_to_encrypt_length) + }.to_vec(); + let mut encrypted_bytes = ::encrypt_plaintext(pub_key_string, data_to_encrypt_slice); + let capacity = encrypted_bytes.capacity(); + encrypted_bytes.reserve_exact(capacity); + let result = RsaEncryptBytesResult { + encrypted_result_ptr: encrypted_bytes.as_mut_ptr(), + length: encrypted_bytes.len(), + }; + std::mem::forget(encrypted_bytes); + return result; +} + +#[no_mangle] +pub extern "C" fn rsa_encrypt_bytes_threadpool( + pub_key: *const c_char, + data_to_encrypt: *const c_uchar, + data_to_encrypt_length: usize, +) -> RsaEncryptBytesResult { + let pub_key_string = unsafe { + assert!(!pub_key.is_null()); + CStr::from_ptr(pub_key) + } + .to_str() + .unwrap() + .to_string(); + + let data_to_encrypt_slice = unsafe { + assert!(!data_to_encrypt.is_null()); + std::slice::from_raw_parts(data_to_encrypt, data_to_encrypt_length) + } + .to_vec(); + + let mut encrypted_bytes = ::encrypt_plaintext_threadpool(pub_key_string, data_to_encrypt_slice); + let capacity = encrypted_bytes.capacity(); + encrypted_bytes.reserve_exact(capacity); + let result = RsaEncryptBytesResult { + encrypted_result_ptr: encrypted_bytes.as_mut_ptr(), + length: encrypted_bytes.len(), + }; + std::mem::forget(encrypted_bytes); + return result; +} + +#[no_mangle] +pub extern "C" fn rsa_decrypt_bytes( + priv_key: *const c_char, + data_to_decrypt: *const c_uchar, + data_to_decrypt_length: usize, +) -> RsaDecryptBytesResult { + let priv_key_string = unsafe { + assert!(!priv_key.is_null()); + CStr::from_ptr(priv_key) + } + .to_str() + .unwrap() + .to_string(); + + let data_to_decrypt_slice = unsafe { + assert!(!data_to_decrypt.is_null()); + std::slice::from_raw_parts(data_to_decrypt, data_to_decrypt_length) + }.to_vec(); + + let mut decrypted_bytes = ::decrypt_ciphertext(priv_key_string, data_to_decrypt_slice); + let capacity = decrypted_bytes.capacity(); + decrypted_bytes.reserve_exact(capacity); + let result = RsaDecryptBytesResult { + decrypted_result_ptr: decrypted_bytes.as_mut_ptr(), + length: decrypted_bytes.len(), + }; + std::mem::forget(decrypted_bytes); + return result; +} + +#[no_mangle] +pub extern "C" fn rsa_decrypt_bytes_threadpool( + priv_key: *const c_char, + data_to_decrypt: *const c_uchar, + data_to_decrypt_length: usize, +) -> RsaDecryptBytesResult { + let priv_key_string = unsafe { + assert!(!priv_key.is_null()); + CStr::from_ptr(priv_key) + } + .to_str() + .unwrap() + .to_string(); + + let data_to_decrypt_slice = unsafe { + assert!(!data_to_decrypt.is_null()); + std::slice::from_raw_parts(data_to_decrypt, data_to_decrypt_length) + }.to_vec(); + let mut decrypted_bytes = ::decrypt_ciphertext_threadpool(priv_key_string, data_to_decrypt_slice); + let capacity = decrypted_bytes.capacity(); + decrypted_bytes.reserve_exact(capacity); + let result = RsaDecryptBytesResult { + decrypted_result_ptr: decrypted_bytes.as_mut_ptr(), + length: decrypted_bytes.len(), + }; + std::mem::forget(decrypted_bytes); + return result; +} + +#[no_mangle] +pub extern "C" fn get_key_pair(key_size: usize) -> RsaKeyPair { + let key_pair = ::generate_rsa_keys(key_size); + let result = RsaKeyPair { + priv_key: CString::new(key_pair.private_key).unwrap().into_raw(), + pub_key: CString::new(key_pair.public_key).unwrap().into_raw() + }; + result +} + +#[no_mangle] +pub extern "C" fn get_key_pair_threadpool(rsa_key_size: usize) -> RsaKeyPair { + let rsa_key_result: RSAKeyPairResult = ::generate_rsa_keys_threadpool(rsa_key_size); + let result = RsaKeyPair { + priv_key: CString::new(rsa_key_result.private_key).unwrap().into_raw(), + pub_key: CString::new(rsa_key_result.public_key).unwrap().into_raw() + }; + result +} + +#[no_mangle] +pub extern "C" fn rsa_sign_with_key_bytes( + private_key: *const c_char, + data_to_sign: *const c_uchar, + data_to_sign_length: usize, +) -> RsaSignBytesResults { + let private_key_string = unsafe { + assert!(!private_key.is_null()); + + CStr::from_ptr(private_key) + } + .to_str() + .unwrap() + .to_string(); + + let data_to_sign_slice = unsafe { + assert!(!data_to_sign.is_null()); + std::slice::from_raw_parts(data_to_sign, data_to_sign_length) + }.to_vec(); + let mut signed_data = ::sign(private_key_string, data_to_sign_slice); + let capacity = signed_data.capacity(); + signed_data.reserve_exact(capacity); + let result = RsaSignBytesResults { + signature_raw_ptr: signed_data.as_mut_ptr(), + length: signed_data.len(), + }; + std::mem::forget(signed_data); + return result; +} + +#[no_mangle] +pub extern "C" fn rsa_sign_with_key_bytes_threadpool( + private_key: *const c_char, + data_to_sign: *const c_uchar, + data_to_sign_length: usize, +) -> RsaSignBytesResults { + let private_key_string = unsafe { + assert!(!private_key.is_null()); + + CStr::from_ptr(private_key) + } + .to_str() + .unwrap() + .to_string(); + + let data_to_sign_slice = unsafe { + assert!(!data_to_sign.is_null()); + std::slice::from_raw_parts(data_to_sign, data_to_sign_length) + }.to_vec(); + + let mut signed_data = ::sign_threadpool(private_key_string, data_to_sign_slice); + let capacity = signed_data.capacity(); + signed_data.reserve_exact(capacity); + let result = RsaSignBytesResults { + signature_raw_ptr: signed_data.as_mut_ptr(), + length: signed_data.len(), + }; + std::mem::forget(signed_data); + return result; +} + +#[no_mangle] +pub extern "C" fn rsa_verify_bytes( + public_key: *const c_char, + data_to_verify: *const c_uchar, + data_to_verify_length: usize, + signature: *const c_uchar, + signature_length: usize, +) -> bool { + let public_key_string = unsafe { + assert!(!public_key.is_null()); + + CStr::from_ptr(public_key) + } + .to_str() + .unwrap() + .to_string(); + + let data_to_verify_slice = unsafe { + assert!(!data_to_verify.is_null()); + std::slice::from_raw_parts(data_to_verify, data_to_verify_length) + }.to_vec(); + + let signature_slice = unsafe { + assert!(!signature.is_null()); + std::slice::from_raw_parts(signature, signature_length) + }.to_vec(); + let verified = ::verify(public_key_string, data_to_verify_slice, signature_slice); + verified +} + +#[no_mangle] +pub extern "C" fn rsa_verify_bytes_threadpool( + public_key: *const c_char, + data_to_verify: *const c_uchar, + data_to_verify_length: usize, + signature: *const c_uchar, + signature_length: usize, +) -> bool { + let public_key_string = unsafe { + assert!(!public_key.is_null()); + + CStr::from_ptr(public_key) + } + .to_str() + .unwrap() + .to_string(); + + let data_to_verify_slice = unsafe { + assert!(!data_to_verify.is_null()); + std::slice::from_raw_parts(data_to_verify, data_to_verify_length) + }.to_vec(); + + let signature_slice = unsafe { + assert!(!signature.is_null()); + std::slice::from_raw_parts(signature, signature_length) + }.to_vec(); + let verified = ::verify_threadpool(public_key_string, data_to_verify_slice, signature_slice); + verified +} + +#[test] +fn get_key_pair_test() { + let key_size = 4096 as usize; + let key_pair = get_key_pair(key_size); + assert!(!key_pair.pub_key.is_null()); + assert!(!key_pair.priv_key.is_null()); +} diff --git a/src/rsa/types.rs b/src/rsa/types.rs new file mode 100644 index 0000000..36159cf --- /dev/null +++ b/src/rsa/types.rs @@ -0,0 +1,25 @@ +use std::ffi::{c_char, c_uchar}; + +#[repr(C)] +pub struct RsaKeyPair { + pub pub_key: *mut c_char, + pub priv_key: *mut c_char, +} + +#[repr(C)] +pub struct RsaSignBytesResults { + pub signature_raw_ptr: *mut c_uchar, + pub length: usize, +} + +#[repr(C)] +pub struct RsaEncryptBytesResult { + pub encrypted_result_ptr: *mut c_uchar, + pub length: usize, +} + +#[repr(C)] +pub struct RsaDecryptBytesResult { + pub decrypted_result_ptr: *mut c_uchar, + pub length: usize, +} \ No newline at end of file diff --git a/src/sha.rs b/src/sha.rs deleted file mode 100644 index 0dc9ef6..0000000 --- a/src/sha.rs +++ /dev/null @@ -1,106 +0,0 @@ -use core::slice; -use std::ffi::c_uchar; - -use sha3::{Digest, Sha3_256, Sha3_512}; - -#[repr(C)] -pub struct SHAHashByteResult { - pub result_bytes_ptr: *mut c_uchar, - pub length: usize, -} - -#[no_mangle] -pub extern "C" fn sha512_bytes(data_to_hash: *const c_uchar, data_len: usize) -> SHAHashByteResult { - assert!(!data_to_hash.is_null()); - let data_to_hash_slice = unsafe { std::slice::from_raw_parts(data_to_hash, data_len) }; - let mut hasher = Sha3_512::new(); - hasher.update(data_to_hash_slice); - let result = hasher.finalize(); - return unsafe { - let size_of_result = std::mem::size_of_val(&result); - let result_raw_ptr = libc::malloc(size_of_result) as *mut c_uchar; - std::ptr::copy_nonoverlapping(result.as_ptr(), result_raw_ptr, size_of_result); - let result = SHAHashByteResult { - result_bytes_ptr: result_raw_ptr, - length: size_of_result, - }; - result - }; -} - -#[no_mangle] -pub extern "C" fn sha512_bytes_verify( - data_to_hash: *const c_uchar, - data_len: usize, - data_to_verify: *const c_uchar, - data_to_verify_len: usize, -) -> bool { - assert!(!data_to_hash.is_null()); - assert!(!data_to_verify.is_null()); - let data_to_hash_slice = unsafe { std::slice::from_raw_parts(data_to_hash, data_len) }; - let data_to_verify_slice = unsafe {std::slice::from_raw_parts(data_to_verify, data_to_verify_len)}; - let mut hasher = Sha3_512::new(); - hasher.update(data_to_hash_slice); - let result = hasher.finalize(); - let result_slice = result.as_slice(); - return data_to_verify_slice.eq(result_slice); -} - -#[test] -fn sha512_bytes_test() { - let data_to_hash = "This is a test hash"; - let data_to_hash_bytes = data_to_hash.as_bytes(); - let data_to_hash_length: usize = data_to_hash_bytes.len(); - let data_to_hash_bytes_ptr = data_to_hash_bytes.as_ptr(); - let result = sha512_bytes(data_to_hash_bytes_ptr, data_to_hash_length); - let result_slice = unsafe { slice::from_raw_parts(result.result_bytes_ptr, result.length) }; - assert_ne!(data_to_hash_bytes, result_slice); -} - -#[no_mangle] -pub extern "C" fn sha256_bytes(data_to_hash: *const c_uchar, data_len: usize) -> SHAHashByteResult { - assert!(!data_to_hash.is_null()); - let data_to_hash_slice = unsafe { std::slice::from_raw_parts(data_to_hash, data_len) }; - let mut hasher = Sha3_256::new(); - hasher.update(data_to_hash_slice); - let result = hasher.finalize(); - return unsafe { - let size_of_result = std::mem::size_of_val(&result); - let result_raw_ptr = libc::malloc(size_of_result) as *mut c_uchar; - std::ptr::copy_nonoverlapping(result.as_ptr(), result_raw_ptr, size_of_result); - let result = SHAHashByteResult { - result_bytes_ptr: result_raw_ptr, - length: size_of_result, - }; - result - }; -} - -#[no_mangle] -pub extern "C" fn sha256_bytes_verify( - data_to_hash: *const c_uchar, - data_len: usize, - data_to_verify: *const c_uchar, - data_to_verify_len: usize, -) -> bool { - assert!(!data_to_hash.is_null()); - assert!(!data_to_verify.is_null()); - let data_to_hash_slice = unsafe { std::slice::from_raw_parts(data_to_hash, data_len) }; - let data_to_verify_slice = unsafe {std::slice::from_raw_parts(data_to_verify, data_to_verify_len)}; - let mut hasher = Sha3_256::new(); - hasher.update(data_to_hash_slice); - let result = hasher.finalize(); - let result_slice = result.as_slice(); - return data_to_verify_slice.eq(result_slice); -} - -#[test] -fn sha256_bytes_test() { - let data_to_hash = "This is a test hash for SHA 256"; - let data_to_hash_bytes = data_to_hash.as_bytes(); - let data_to_hash_length: usize = data_to_hash_bytes.len(); - let data_to_hash_bytes_ptr = data_to_hash_bytes.as_ptr(); - let result = sha256_bytes(data_to_hash_bytes_ptr, data_to_hash_length); - let result_slice = unsafe { slice::from_raw_parts(result.result_bytes_ptr, result.length) }; - assert_ne!(data_to_hash_bytes, result_slice); -} diff --git a/src/sha/mod.rs b/src/sha/mod.rs new file mode 100644 index 0000000..ffe41d6 --- /dev/null +++ b/src/sha/mod.rs @@ -0,0 +1,160 @@ +use core::slice; +use std::{ffi::c_uchar, sync::mpsc}; + +use cas_lib::hashers::{cas_hasher::CASHasher, sha::CASSHA}; + +use self::types::SHAHashByteResult; +mod types; + +#[no_mangle] +pub extern "C" fn sha512_bytes(data_to_hash: *const c_uchar, data_len: usize) -> SHAHashByteResult { + assert!(!data_to_hash.is_null()); + let data_to_hash_slice = unsafe { std::slice::from_raw_parts(data_to_hash, data_len) }.to_vec(); + let mut result = ::hash_512(data_to_hash_slice); + let capacity = result.capacity(); + result.reserve_exact(capacity); + let return_result = SHAHashByteResult { + result_bytes_ptr: result.as_mut_ptr(), + length: result.len(), + }; + std::mem::forget(result); + return_result +} + +#[no_mangle] +pub extern "C" fn sha512_bytes_threadpool( + data_to_hash: *const c_uchar, + data_len: usize, +) -> SHAHashByteResult { + assert!(!data_to_hash.is_null()); + let data_to_hash_slice = unsafe { std::slice::from_raw_parts(data_to_hash, data_len) }.to_vec(); + let mut result = ::hash_512_threadpool(data_to_hash_slice); + let capacity = result.capacity(); + result.reserve_exact(capacity); + let return_result = SHAHashByteResult { + result_bytes_ptr: result.as_mut_ptr(), + length: result.len(), + }; + std::mem::forget(result); + return_result +} + +#[no_mangle] +pub extern "C" fn sha512_bytes_verify( + data_to_hash: *const c_uchar, + data_len: usize, + data_to_verify: *const c_uchar, + data_to_verify_len: usize, +) -> bool { + assert!(!data_to_hash.is_null()); + assert!(!data_to_verify.is_null()); + let data_to_hash_slice = unsafe { std::slice::from_raw_parts(data_to_hash, data_len) }.to_vec(); + let data_to_verify_slice = + unsafe { std::slice::from_raw_parts(data_to_verify, data_to_verify_len) }.to_vec(); + let result = ::verify_512(data_to_verify_slice, data_to_hash_slice); + result +} + +#[no_mangle] +pub extern "C" fn sha512_bytes_verify_threadpool( + data_to_hash: *const c_uchar, + data_len: usize, + data_to_verify: *const c_uchar, + data_to_verify_len: usize, +) -> bool { + assert!(!data_to_hash.is_null()); + assert!(!data_to_verify.is_null()); + let data_to_hash_slice = unsafe { std::slice::from_raw_parts(data_to_hash, data_len) }.to_vec(); + let data_to_verify_slice = + unsafe { std::slice::from_raw_parts(data_to_verify, data_to_verify_len) }.to_vec(); + let result = + ::verify_512_threadpool(data_to_verify_slice, data_to_hash_slice); + result +} + +#[test] +fn sha512_bytes_test() { + let data_to_hash = "This is a test hash"; + let data_to_hash_bytes = data_to_hash.as_bytes(); + let data_to_hash_length: usize = data_to_hash_bytes.len(); + let data_to_hash_bytes_ptr = data_to_hash_bytes.as_ptr(); + let result = sha512_bytes(data_to_hash_bytes_ptr, data_to_hash_length); + let result_slice = unsafe { slice::from_raw_parts(result.result_bytes_ptr, result.length) }; + assert_ne!(data_to_hash_bytes, result_slice); +} + +#[no_mangle] +pub extern "C" fn sha256_bytes(data_to_hash: *const c_uchar, data_len: usize) -> SHAHashByteResult { + assert!(!data_to_hash.is_null()); + let data_to_hash_slice = unsafe { std::slice::from_raw_parts(data_to_hash, data_len) }.to_vec(); + let mut result = ::hash_256(data_to_hash_slice); + let capacity = result.capacity(); + result.reserve_exact(capacity); + let return_result = SHAHashByteResult { + result_bytes_ptr: result.as_mut_ptr(), + length: result.len(), + }; + std::mem::forget(result); + return_result +} + +#[no_mangle] +pub extern "C" fn sha256_bytes_threadpool( + data_to_hash: *const c_uchar, + data_len: usize, +) -> SHAHashByteResult { + assert!(!data_to_hash.is_null()); + let data_to_hash_slice = unsafe { std::slice::from_raw_parts(data_to_hash, data_len) }.to_vec(); + let mut result = ::hash_256_threadpool(data_to_hash_slice); + let capacity = result.capacity(); + result.reserve_exact(capacity); + let return_result = SHAHashByteResult { + result_bytes_ptr: result.as_mut_ptr(), + length: result.len(), + }; + std::mem::forget(result); + return_result +} + +#[no_mangle] +pub extern "C" fn sha256_bytes_verify( + data_to_hash: *const c_uchar, + data_len: usize, + data_to_verify: *const c_uchar, + data_to_verify_len: usize, +) -> bool { + assert!(!data_to_hash.is_null()); + assert!(!data_to_verify.is_null()); + let data_to_hash_slice = unsafe { std::slice::from_raw_parts(data_to_hash, data_len) }.to_vec(); + let data_to_verify_slice = + unsafe { std::slice::from_raw_parts(data_to_verify, data_to_verify_len) }.to_vec(); + let result = ::verify_256(data_to_verify_slice, data_to_hash_slice); + result +} + +#[no_mangle] +pub extern "C" fn sha256_bytes_verify_threadpool( + data_to_hash: *const c_uchar, + data_len: usize, + data_to_verify: *const c_uchar, + data_to_verify_len: usize, +) -> bool { + assert!(!data_to_hash.is_null()); + assert!(!data_to_verify.is_null()); + let data_to_hash_slice = unsafe { std::slice::from_raw_parts(data_to_hash, data_len) }.to_vec(); + let data_to_verify_slice = + unsafe { std::slice::from_raw_parts(data_to_verify, data_to_verify_len) }.to_vec(); + let result = ::verify_256_threadpool(data_to_verify_slice, data_to_hash_slice); + result +} + +#[test] +fn sha256_bytes_test() { + let data_to_hash = "This is a test hash for SHA 256"; + let data_to_hash_bytes = data_to_hash.as_bytes(); + let data_to_hash_length: usize = data_to_hash_bytes.len(); + let data_to_hash_bytes_ptr = data_to_hash_bytes.as_ptr(); + let result = sha256_bytes(data_to_hash_bytes_ptr, data_to_hash_length); + let result_slice = unsafe { slice::from_raw_parts(result.result_bytes_ptr, result.length) }; + assert_ne!(data_to_hash_bytes, result_slice); +} diff --git a/src/sha/types.rs b/src/sha/types.rs new file mode 100644 index 0000000..be37a84 --- /dev/null +++ b/src/sha/types.rs @@ -0,0 +1,7 @@ +use std::ffi::c_uchar; + +#[repr(C)] +pub struct SHAHashByteResult { + pub result_bytes_ptr: *mut c_uchar, + pub length: usize, +} \ No newline at end of file diff --git a/src/x25519.rs b/src/x25519.rs index 2780c65..4559a88 100644 --- a/src/x25519.rs +++ b/src/x25519.rs @@ -1,6 +1,5 @@ -use rsa::rand_core::OsRng; +use cas_lib::key_exchange::{cas_key_exchange::CASKeyExchange, x25519::X25519}; use std::ffi::c_uchar; -use x25519_dalek::{PublicKey, StaticSecret}; #[repr(C)] pub struct x25519SecretPublicKeyResult { @@ -18,27 +17,42 @@ pub struct x25519SharedSecretResult { #[no_mangle] pub extern "C" fn generate_secret_and_public_key() -> x25519SecretPublicKeyResult { - let secret_key = StaticSecret::random_from_rng(&mut OsRng); - let public_key = PublicKey::from(&secret_key); - let secret_key_bytes = secret_key.to_bytes(); - let public_key_bytes = public_key.to_bytes(); - return unsafe { - let size_secret_key = std::mem::size_of_val(&secret_key_bytes); - let secret_key_ptr = libc::malloc(size_secret_key) as *mut c_uchar; - std::ptr::copy_nonoverlapping(secret_key_bytes.as_ptr(), secret_key_ptr, size_secret_key); - - let size_public_key = std::mem::size_of_val(&public_key_bytes); - let public_key_ptr = libc::malloc(size_public_key) as *mut c_uchar; - std::ptr::copy_nonoverlapping(public_key_bytes.as_ptr(), public_key_ptr, size_public_key); + let result = ::generate_secret_and_public_key(); + let mut secret_key = result.secret_key; + let mut public_key = result.public_key; + let secret_key_capacity = secret_key.capacity(); + secret_key.reserve_exact(secret_key_capacity); + let public_key_capacity = public_key.capacity(); + public_key.reserve_exact(public_key_capacity); + let result = x25519SecretPublicKeyResult { + secret_key: secret_key.as_mut_ptr(), + secret_key_length: secret_key.len(), + public_key: public_key.as_mut_ptr(), + public_key_length: public_key.len(), + }; + std::mem::forget(public_key); + std::mem::forget(secret_key); + result +} - let result = x25519SecretPublicKeyResult { - secret_key: secret_key_ptr, - secret_key_length: size_secret_key, - public_key: public_key_ptr, - public_key_length: size_public_key, - }; - result +#[no_mangle] +pub extern "C" fn generate_secret_and_public_key_threadpool() -> x25519SecretPublicKeyResult { + let result = ::generate_secret_and_public_key_threadpool(); + let mut secret_key = result.secret_key; + let mut public_key = result.public_key; + let secret_key_capacity = secret_key.capacity(); + secret_key.reserve_exact(secret_key_capacity); + let public_key_capacity = public_key.capacity(); + public_key.reserve_exact(public_key_capacity); + let result = x25519SecretPublicKeyResult { + secret_key: secret_key.as_mut_ptr(), + secret_key_length: secret_key.len(), + public_key: public_key.as_mut_ptr(), + public_key_length: public_key.len(), }; + std::mem::forget(public_key); + std::mem::forget(secret_key); + result } #[test] @@ -84,32 +98,43 @@ pub extern "C" fn diffie_hellman( other_user_public_key: *const c_uchar, other_user_public_key_length: usize, ) -> x25519SharedSecretResult { - let secret_key_slice = unsafe { std::slice::from_raw_parts(secret_key, secret_key_length) }; + let secret_key_slice = + unsafe { std::slice::from_raw_parts(secret_key, secret_key_length) }.to_vec(); let other_user_public_key = - unsafe { std::slice::from_raw_parts(other_user_public_key, other_user_public_key_length) }; - - let mut secret_key_array: [u8; 32] = Default::default(); - secret_key_array.copy_from_slice(&secret_key_slice); - - let mut other_user_public_key_array: [u8; 32] = Default::default(); - other_user_public_key_array.copy_from_slice(&other_user_public_key); - - let secret_key = StaticSecret::from(secret_key_array); - let public_key = PublicKey::from(other_user_public_key_array); - let shared_secret = secret_key.diffie_hellman(&public_key); - let shared_secret_bytes = shared_secret.to_bytes(); - return unsafe { - let size_shared_secret = std::mem::size_of_val(&shared_secret_bytes); - let shared_secret_ptr = libc::malloc(size_shared_secret) as *mut c_uchar; - std::ptr::copy_nonoverlapping( - shared_secret_bytes.as_ptr(), - shared_secret_ptr, - size_shared_secret, - ); - let result = x25519SharedSecretResult { - shared_secret: shared_secret_ptr, - shared_secret_length: size_shared_secret, - }; - result + unsafe { std::slice::from_raw_parts(other_user_public_key, other_user_public_key_length) } + .to_vec(); + let mut result = + ::diffie_hellman(secret_key_slice, other_user_public_key); + let capacity = result.capacity(); + result.reserve_exact(capacity); + let return_result = x25519SharedSecretResult { + shared_secret: result.as_mut_ptr(), + shared_secret_length: result.len(), }; + std::mem::forget(result); + return_result } + +#[no_mangle] +pub extern "C" fn diffie_hellman_threadpool( + secret_key: *const c_uchar, + secret_key_length: usize, + other_user_public_key: *const c_uchar, + other_user_public_key_length: usize, +) -> x25519SharedSecretResult { + let secret_key_slice = + unsafe { std::slice::from_raw_parts(secret_key, secret_key_length) }.to_vec(); + let other_user_public_key = + unsafe { std::slice::from_raw_parts(other_user_public_key, other_user_public_key_length) } + .to_vec(); + let mut result = + ::diffie_hellman_threadpool(secret_key_slice, other_user_public_key); + let capacity = result.capacity(); + result.reserve_exact(capacity); + let return_result = x25519SharedSecretResult { + shared_secret: result.as_mut_ptr(), + shared_secret_length: result.len(), + }; + std::mem::forget(result); + return_result +} \ No newline at end of file