#![cfg(aes)]
use crate::sys;
use core::mem::{size_of_val, MaybeUninit};
#[cfg(aes_wc_block_size)]
pub const AES_BLOCK_SIZE: usize = sys::WC_AES_BLOCK_SIZE as usize;
#[cfg(not(aes_wc_block_size))]
pub const AES_BLOCK_SIZE: usize = sys::AES_BLOCK_SIZE as usize;
#[cfg(aes_cbc)]
pub struct CBC {
ws_aes: sys::Aes,
}
#[cfg(aes_cbc)]
impl CBC {
pub fn new() -> Result<Self, i32> {
Self::new_ex(None, None)
}
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
let ws_aes = new_ws_aes(heap, dev_id)?;
let cbc = CBC { ws_aes };
Ok(cbc)
}
fn init(&mut self, key: &[u8], iv: &[u8], dir: i32) -> Result<(), i32> {
let key_size = key.len() as u32;
if iv.len() != AES_BLOCK_SIZE {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesSetKey(&mut self.ws_aes, key.as_ptr(), key_size, iv.as_ptr(), dir)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn init_encrypt(&mut self, key: &[u8], iv: &[u8]) -> Result<(), i32> {
self.init(key, iv, sys::AES_ENCRYPTION as i32)
}
pub fn init_decrypt(&mut self, key: &[u8], iv: &[u8]) -> Result<(), i32> {
self.init(key, iv, sys::AES_DECRYPTION as i32)
}
pub fn encrypt<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe { sys::wc_AesCbcEncrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe { sys::wc_AesCbcDecrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_cbc)]
impl Drop for CBC {
fn drop(&mut self) {
unsafe {
sys::wc_AesFree(&mut self.ws_aes);
}
}
}
#[cfg(aes_ccm)]
pub struct CCM {
ws_aes: sys::Aes,
}
#[cfg(aes_ccm)]
impl CCM {
pub fn new() -> Result<Self, i32> {
Self::new_ex(None, None)
}
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
let ws_aes = new_ws_aes(heap, dev_id)?;
let ccm = CCM { ws_aes };
Ok(ccm)
}
pub fn init(&mut self, key: &[u8]) -> Result<(), i32> {
let key_size = key.len() as u32;
let rc = unsafe { sys::wc_AesCcmSetKey(&mut self.ws_aes, key.as_ptr(), key_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt<I, O, N, A>(
&mut self,
din: &[I],
dout: &mut [O],
nonce: &[N],
auth: &[A],
auth_tag: &mut [A],
) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
let nonce_ptr = nonce.as_ptr() as *const u8;
let nonce_size = size_of_val(nonce) as u32;
let auth_ptr = auth.as_ptr() as *const u8;
let auth_size = size_of_val(auth) as u32;
let auth_tag_ptr = auth_tag.as_mut_ptr() as *mut u8;
let auth_tag_size = size_of_val(auth_tag) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesCcmEncrypt(
&mut self.ws_aes,
out_ptr,
in_ptr,
in_size,
nonce_ptr,
nonce_size,
auth_tag_ptr,
auth_tag_size,
auth_ptr,
auth_size,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt<I, O, N, A>(
&mut self,
din: &[I],
dout: &mut [O],
nonce: &[N],
auth: &[A],
auth_tag: &[A],
) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
let nonce_ptr = nonce.as_ptr() as *const u8;
let nonce_size = size_of_val(nonce) as u32;
let auth_ptr = auth.as_ptr() as *const u8;
let auth_size = size_of_val(auth) as u32;
let auth_tag_ptr = auth_tag.as_ptr() as *const u8;
let auth_tag_size = size_of_val(auth_tag) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesCcmDecrypt(
&mut self.ws_aes,
out_ptr,
in_ptr,
in_size,
nonce_ptr,
nonce_size,
auth_tag_ptr,
auth_tag_size,
auth_ptr,
auth_size,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_ccm)]
impl Drop for CCM {
fn drop(&mut self) {
unsafe {
sys::wc_AesFree(&mut self.ws_aes);
}
}
}
#[cfg(aes_cfb)]
pub struct CFB {
ws_aes: sys::Aes,
}
#[cfg(aes_cfb)]
impl CFB {
pub fn new() -> Result<Self, i32> {
Self::new_ex(None, None)
}
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
let ws_aes = new_ws_aes(heap, dev_id)?;
let cfb = CFB { ws_aes };
Ok(cfb)
}
pub fn init(&mut self, key: &[u8], iv: &[u8]) -> Result<(), i32> {
let key_size = key.len() as u32;
if iv.len() != AES_BLOCK_SIZE {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesSetKey(
&mut self.ws_aes,
key.as_ptr(),
key_size,
iv.as_ptr(),
sys::AES_ENCRYPTION as i32,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe { sys::wc_AesCfbEncrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt1<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe { sys::wc_AesCfb1Encrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt8<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe { sys::wc_AesCfb8Encrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
#[cfg(aes_decrypt)]
pub fn decrypt<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe { sys::wc_AesCfbDecrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
#[cfg(aes_decrypt)]
pub fn decrypt1<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe { sys::wc_AesCfb1Decrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
#[cfg(aes_decrypt)]
pub fn decrypt8<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe { sys::wc_AesCfb8Decrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_cfb)]
impl Drop for CFB {
fn drop(&mut self) {
unsafe {
sys::wc_AesFree(&mut self.ws_aes);
}
}
}
#[cfg(aes_ctr)]
pub struct CTR {
ws_aes: sys::Aes,
}
#[cfg(aes_ctr)]
impl CTR {
pub fn new() -> Result<Self, i32> {
Self::new_ex(None, None)
}
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
let ws_aes = new_ws_aes(heap, dev_id)?;
let ctr = CTR { ws_aes };
Ok(ctr)
}
pub fn init(&mut self, key: &[u8], iv: &[u8]) -> Result<(), i32> {
let key_size = key.len() as u32;
if iv.len() != AES_BLOCK_SIZE {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesSetKeyDirect(
&mut self.ws_aes,
key.as_ptr(),
key_size,
iv.as_ptr(),
sys::AES_ENCRYPTION as i32,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
fn encrypt_decrypt<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe { sys::wc_AesCtrEncrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
self.encrypt_decrypt(din, dout)
}
pub fn decrypt<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
self.encrypt_decrypt(din, dout)
}
}
#[cfg(aes_ctr)]
impl Drop for CTR {
fn drop(&mut self) {
unsafe {
sys::wc_AesFree(&mut self.ws_aes);
}
}
}
#[cfg(aes_eax)]
pub struct EAX {}
#[cfg(aes_eax)]
impl EAX {
pub fn encrypt<I, O>(
din: &[I],
dout: &mut [O],
key: &[u8],
nonce: &[u8],
auth: &[u8],
auth_tag: &mut [u8],
) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
let key_size = key.len() as u32;
let nonce_size = nonce.len() as u32;
let auth_size = auth.len() as u32;
let auth_tag_size = auth_tag.len() as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesEaxEncryptAuth(
key.as_ptr(),
key_size,
out_ptr,
in_ptr,
in_size,
nonce.as_ptr(),
nonce_size,
auth_tag.as_mut_ptr(),
auth_tag_size,
auth.as_ptr(),
auth_size,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt<I, O>(
din: &[I],
dout: &mut [O],
key: &[u8],
nonce: &[u8],
auth: &[u8],
auth_tag: &[u8],
) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
let key_size = key.len() as u32;
let nonce_size = nonce.len() as u32;
let auth_size = auth.len() as u32;
let auth_tag_size = auth_tag.len() as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesEaxDecryptAuth(
key.as_ptr(),
key_size,
out_ptr,
in_ptr,
in_size,
nonce.as_ptr(),
nonce_size,
auth_tag.as_ptr(),
auth_tag_size,
auth.as_ptr(),
auth_size,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_ecb)]
pub struct ECB {
ws_aes: sys::Aes,
}
#[cfg(aes_ecb)]
impl ECB {
pub fn new() -> Result<Self, i32> {
Self::new_ex(None, None)
}
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
let ws_aes = new_ws_aes(heap, dev_id)?;
let ecb = ECB { ws_aes };
Ok(ecb)
}
fn init(&mut self, key: &[u8], dir: i32) -> Result<(), i32> {
let key_size = key.len() as u32;
let rc = unsafe {
sys::wc_AesSetKey(
&mut self.ws_aes,
key.as_ptr(),
key_size,
core::ptr::null(),
dir,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn init_encrypt(&mut self, key: &[u8]) -> Result<(), i32> {
self.init(key, sys::AES_ENCRYPTION as i32)
}
pub fn init_decrypt(&mut self, key: &[u8]) -> Result<(), i32> {
self.init(key, sys::AES_DECRYPTION as i32)
}
pub fn encrypt<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe { sys::wc_AesEcbEncrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe { sys::wc_AesEcbDecrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_ecb)]
impl Drop for ECB {
fn drop(&mut self) {
unsafe {
sys::wc_AesFree(&mut self.ws_aes);
}
}
}
#[cfg(aes_gcm)]
pub struct GCM {
ws_aes: sys::Aes,
}
#[cfg(aes_gcm)]
impl GCM {
pub fn new() -> Result<Self, i32> {
Self::new_ex(None, None)
}
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
let ws_aes = new_ws_aes(heap, dev_id)?;
let gcm = GCM { ws_aes };
Ok(gcm)
}
pub fn init(&mut self, key: &[u8]) -> Result<(), i32> {
let key_size = key.len() as u32;
let rc = unsafe { sys::wc_AesGcmSetKey(&mut self.ws_aes, key.as_ptr(), key_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt<I, O>(
&mut self,
din: &[I],
dout: &mut [O],
iv: &[u8],
auth: &[u8],
auth_tag: &mut [u8],
) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
let iv_size = iv.len() as u32;
let auth_size = auth.len() as u32;
let auth_tag_size = auth_tag.len() as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesGcmEncrypt(
&mut self.ws_aes,
out_ptr,
in_ptr,
in_size,
iv.as_ptr(),
iv_size,
auth_tag.as_mut_ptr(),
auth_tag_size,
auth.as_ptr(),
auth_size,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt<I, O>(
&mut self,
din: &[I],
dout: &mut [O],
iv: &[u8],
auth: &[u8],
auth_tag: &[u8],
) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
let iv_size = iv.len() as u32;
let auth_size = auth.len() as u32;
let auth_tag_size = auth_tag.len() as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesGcmDecrypt(
&mut self.ws_aes,
out_ptr,
in_ptr,
in_size,
iv.as_ptr(),
iv_size,
auth_tag.as_ptr(),
auth_tag_size,
auth.as_ptr(),
auth_size,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_gcm)]
impl Drop for GCM {
fn drop(&mut self) {
unsafe {
sys::wc_AesFree(&mut self.ws_aes);
}
}
}
#[cfg(aes_gcm_stream)]
pub struct GCMStream {
ws_aes: sys::Aes,
}
#[cfg(aes_gcm_stream)]
impl GCMStream {
pub fn new() -> Result<Self, i32> {
Self::new_ex(None, None)
}
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
let ws_aes = new_ws_aes(heap, dev_id)?;
let gcmstream = GCMStream { ws_aes };
Ok(gcmstream)
}
pub fn init(&mut self, key: &[u8], iv: &[u8]) -> Result<(), i32> {
let key_size = key.len() as u32;
let iv_size = iv.len() as u32;
let rc = unsafe {
sys::wc_AesGcmInit(
&mut self.ws_aes,
key.as_ptr(),
key_size,
iv.as_ptr(),
iv_size,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt_update<I, O>(
&mut self,
din: &[I],
dout: &mut [O],
auth: &[u8],
) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
let auth_size = auth.len() as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesGcmEncryptUpdate(
&mut self.ws_aes,
out_ptr,
in_ptr,
in_size,
auth.as_ptr(),
auth_size,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt_final(&mut self, auth_tag: &mut [u8]) -> Result<(), i32> {
let auth_tag_size = auth_tag.len() as u32;
let rc = unsafe {
sys::wc_AesGcmEncryptFinal(&mut self.ws_aes, auth_tag.as_mut_ptr(), auth_tag_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt_update<I, O>(
&mut self,
din: &[I],
dout: &mut [O],
auth: &[u8],
) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
let auth_size = auth.len() as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesGcmDecryptUpdate(
&mut self.ws_aes,
out_ptr,
in_ptr,
in_size,
auth.as_ptr(),
auth_size,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt_final(&mut self, auth_tag: &[u8]) -> Result<(), i32> {
let auth_tag_size = auth_tag.len() as u32;
let rc = unsafe {
sys::wc_AesGcmDecryptFinal(&mut self.ws_aes, auth_tag.as_ptr(), auth_tag_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_gcm_stream)]
impl Drop for GCMStream {
fn drop(&mut self) {
unsafe {
sys::wc_AesFree(&mut self.ws_aes);
}
}
}
#[cfg(aes_ofb)]
pub struct OFB {
ws_aes: sys::Aes,
}
#[cfg(aes_ofb)]
impl OFB {
pub fn new() -> Result<Self, i32> {
Self::new_ex(None, None)
}
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
let ws_aes = new_ws_aes(heap, dev_id)?;
let ofb = OFB { ws_aes };
Ok(ofb)
}
pub fn init(&mut self, key: &[u8], iv: &[u8]) -> Result<(), i32> {
let key_size = key.len() as u32;
if iv.len() != AES_BLOCK_SIZE {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesSetKey(
&mut self.ws_aes,
key.as_ptr(),
key_size,
iv.as_ptr(),
sys::AES_ENCRYPTION as i32,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe { sys::wc_AesOfbEncrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
#[cfg(aes_decrypt)]
pub fn decrypt<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe { sys::wc_AesOfbDecrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_ofb)]
impl Drop for OFB {
fn drop(&mut self) {
unsafe {
sys::wc_AesFree(&mut self.ws_aes);
}
}
}
#[cfg(aes_xts)]
pub struct XTS {
ws_xtsaes: sys::XtsAes,
}
#[cfg(aes_xts)]
impl XTS {
pub fn new() -> Result<Self, i32> {
Self::new_ex(None, None)
}
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
let ws_xtsaes = new_ws_xtsaes(heap, dev_id)?;
let xts = XTS { ws_xtsaes };
Ok(xts)
}
fn init(&mut self, key: &[u8], dir: i32) -> Result<(), i32> {
let key_size = key.len() as u32;
let rc =
unsafe { sys::wc_AesXtsSetKeyNoInit(&mut self.ws_xtsaes, key.as_ptr(), key_size, dir) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn init_encrypt(&mut self, key: &[u8]) -> Result<(), i32> {
self.init(key, sys::AES_ENCRYPTION as i32)
}
pub fn init_decrypt(&mut self, key: &[u8]) -> Result<(), i32> {
self.init(key, sys::AES_DECRYPTION as i32)
}
pub fn encrypt<I, O>(&mut self, din: &[I], dout: &mut [O], tweak: &[u8]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
let tweak_size = tweak.len() as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsEncrypt(
&mut self.ws_xtsaes,
out_ptr,
in_ptr,
in_size,
tweak.as_ptr(),
tweak_size,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt_sector<I, O>(
&mut self,
din: &[I],
dout: &mut [O],
sector: u64,
) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsEncryptSector(&mut self.ws_xtsaes, out_ptr, in_ptr, in_size, sector)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt_consecutive_sectors<I, O>(
&mut self,
din: &[I],
dout: &mut [O],
sector: u64,
sector_size: u32,
) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsEncryptConsecutiveSectors(
&mut self.ws_xtsaes,
out_ptr,
in_ptr,
in_size,
sector,
sector_size,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt<I, O>(&mut self, din: &[I], dout: &mut [O], tweak: &[u8]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
let tweak_size = tweak.len() as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsDecrypt(
&mut self.ws_xtsaes,
out_ptr,
in_ptr,
in_size,
tweak.as_ptr(),
tweak_size,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt_sector<I, O>(
&mut self,
din: &[I],
dout: &mut [O],
sector: u64,
) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsDecryptSector(&mut self.ws_xtsaes, out_ptr, in_ptr, in_size, sector)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt_consecutive_sectors<I, O>(
&mut self,
din: &[I],
dout: &mut [O],
sector: u64,
sector_size: u32,
) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_mut_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsDecryptConsecutiveSectors(
&mut self.ws_xtsaes,
out_ptr,
in_ptr,
in_size,
sector,
sector_size,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_xts)]
impl Drop for XTS {
fn drop(&mut self) {
unsafe {
sys::wc_AesXtsFree(&mut self.ws_xtsaes);
}
}
}
#[cfg(aes_xts_stream)]
pub struct XTSStream {
ws_xtsaes: sys::XtsAes,
ws_xtsaesstreamdata: sys::XtsAesStreamData,
}
#[cfg(aes_xts_stream)]
impl XTSStream {
pub fn new() -> Result<Self, i32> {
Self::new_ex(None, None)
}
pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
let ws_xtsaes = new_ws_xtsaes(heap, dev_id)?;
let ws_xtsaesstreamdata: MaybeUninit<sys::XtsAesStreamData> = MaybeUninit::uninit();
let ws_xtsaesstreamdata = unsafe { ws_xtsaesstreamdata.assume_init() };
let xtsstream = XTSStream {
ws_xtsaes,
ws_xtsaesstreamdata,
};
Ok(xtsstream)
}
pub fn init_encrypt(&mut self, key: &[u8], tweak: &[u8]) -> Result<(), i32> {
let key_size = key.len() as u32;
let rc = unsafe {
sys::wc_AesXtsSetKeyNoInit(
&mut self.ws_xtsaes,
key.as_ptr(),
key_size,
sys::AES_ENCRYPTION as i32,
)
};
if rc != 0 {
return Err(rc);
}
let tweak_size = tweak.len() as u32;
let rc = unsafe {
sys::wc_AesXtsEncryptInit(
&mut self.ws_xtsaes,
tweak.as_ptr(),
tweak_size,
&mut self.ws_xtsaesstreamdata,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn init_decrypt(&mut self, key: &[u8], tweak: &[u8]) -> Result<(), i32> {
let key_size = key.len() as u32;
let rc = unsafe {
sys::wc_AesXtsSetKeyNoInit(
&mut self.ws_xtsaes,
key.as_ptr(),
key_size,
sys::AES_DECRYPTION as i32,
)
};
if rc != 0 {
return Err(rc);
}
let tweak_size = tweak.len() as u32;
let rc = unsafe {
sys::wc_AesXtsDecryptInit(
&mut self.ws_xtsaes,
tweak.as_ptr(),
tweak_size,
&mut self.ws_xtsaesstreamdata,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt_update<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsEncryptUpdate(
&mut self.ws_xtsaes,
out_ptr,
in_ptr,
in_size,
&mut self.ws_xtsaesstreamdata,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt_final<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsEncryptFinal(
&mut self.ws_xtsaes,
out_ptr,
in_ptr,
in_size,
&mut self.ws_xtsaesstreamdata,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt_update<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsDecryptUpdate(
&mut self.ws_xtsaes,
out_ptr,
in_ptr,
in_size,
&mut self.ws_xtsaesstreamdata,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt_final<I, O>(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> {
let in_ptr = din.as_ptr() as *const u8;
let in_size = size_of_val(din) as u32;
let out_ptr = dout.as_ptr() as *mut u8;
let out_size = size_of_val(dout) as u32;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsDecryptFinal(
&mut self.ws_xtsaes,
out_ptr,
in_ptr,
in_size,
&mut self.ws_xtsaesstreamdata,
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_xts_stream)]
impl Drop for XTSStream {
fn drop(&mut self) {
unsafe {
sys::wc_AesXtsFree(&mut self.ws_xtsaes);
}
}
}
fn new_ws_aes(heap: Option<*mut core::ffi::c_void>, dev_id: Option<i32>) -> Result<sys::Aes, i32> {
let heap = match heap {
Some(heap) => heap,
None => core::ptr::null_mut(),
};
let dev_id = match dev_id {
Some(dev_id) => dev_id,
None => sys::INVALID_DEVID,
};
let mut ws_aes: MaybeUninit<sys::Aes> = MaybeUninit::uninit();
let rc = unsafe { sys::wc_AesInit(ws_aes.as_mut_ptr(), heap, dev_id) };
if rc != 0 {
return Err(rc);
}
let ws_aes = unsafe { ws_aes.assume_init() };
Ok(ws_aes)
}
#[cfg(any(aes_xts, aes_xts_stream))]
fn new_ws_xtsaes(
heap: Option<*mut core::ffi::c_void>,
dev_id: Option<i32>,
) -> Result<sys::XtsAes, i32> {
let heap = match heap {
Some(heap) => heap,
None => core::ptr::null_mut(),
};
let dev_id = match dev_id {
Some(dev_id) => dev_id,
None => sys::INVALID_DEVID,
};
let mut ws_xtsaes: MaybeUninit<sys::XtsAes> = MaybeUninit::uninit();
let rc = unsafe { sys::wc_AesXtsInit(ws_xtsaes.as_mut_ptr(), heap, dev_id) };
if rc != 0 {
return Err(rc);
}
let ws_xtsaes = unsafe { ws_xtsaes.assume_init() };
Ok(ws_xtsaes)
}