use crate::error::{check, WolfCryptError};
pub struct AesXts {
xts: wolfcrypt_rs::XtsAes,
direction: i32,
}
unsafe impl Send for AesXts {}
impl Drop for AesXts {
fn drop(&mut self) {
unsafe {
wolfcrypt_rs::wc_AesXtsFree(&mut self.xts as *mut wolfcrypt_rs::XtsAes);
}
}
}
impl AesXts {
pub fn new_encrypt(key: &[u8]) -> Result<Self, WolfCryptError> {
Self::new_inner(key, wolfcrypt_rs::AES_ENCRYPT)
}
pub fn new_decrypt(key: &[u8]) -> Result<Self, WolfCryptError> {
Self::new_inner(key, wolfcrypt_rs::AES_DECRYPT)
}
fn new_inner(key: &[u8], dir: i32) -> Result<Self, WolfCryptError> {
if key.len() != 32 && key.len() != 64 {
return Err(WolfCryptError::InvalidInput);
}
let mut xts = wolfcrypt_rs::XtsAes::zeroed();
let rc = unsafe {
wolfcrypt_rs::wc_AesXtsInit(
&mut xts as *mut wolfcrypt_rs::XtsAes,
core::ptr::null_mut(),
wolfcrypt_rs::INVALID_DEVID,
)
};
check(rc, "wc_AesXtsInit")?;
let rc = unsafe {
wolfcrypt_rs::wc_AesXtsSetKeyNoInit(
&mut xts as *mut wolfcrypt_rs::XtsAes,
key.as_ptr(),
key.len() as u32,
dir,
)
};
if rc != 0 {
unsafe {
wolfcrypt_rs::wc_AesXtsFree(&mut xts as *mut wolfcrypt_rs::XtsAes);
}
return Err(WolfCryptError::Ffi {
code: rc,
func: "wc_AesXtsSetKeyNoInit",
});
}
Ok(Self {
xts,
direction: dir,
})
}
pub fn encrypt(
&mut self,
out: &mut [u8],
input: &[u8],
tweak: &[u8],
) -> Result<(), WolfCryptError> {
if self.direction != wolfcrypt_rs::AES_ENCRYPT {
return Err(WolfCryptError::InvalidInput);
}
if out.len() < input.len() || input.len() < 16 {
return Err(WolfCryptError::InvalidInput);
}
let rc = unsafe {
wolfcrypt_rs::wc_AesXtsEncrypt(
&mut self.xts as *mut wolfcrypt_rs::XtsAes,
out.as_mut_ptr(),
input.as_ptr(),
input.len() as u32,
tweak.as_ptr(),
tweak.len() as u32,
)
};
check(rc, "wc_AesXtsEncrypt")?;
Ok(())
}
pub fn decrypt(
&mut self,
out: &mut [u8],
input: &[u8],
tweak: &[u8],
) -> Result<(), WolfCryptError> {
if self.direction != wolfcrypt_rs::AES_DECRYPT {
return Err(WolfCryptError::InvalidInput);
}
if out.len() < input.len() || input.len() < 16 {
return Err(WolfCryptError::InvalidInput);
}
let rc = unsafe {
wolfcrypt_rs::wc_AesXtsDecrypt(
&mut self.xts as *mut wolfcrypt_rs::XtsAes,
out.as_mut_ptr(),
input.as_ptr(),
input.len() as u32,
tweak.as_ptr(),
tweak.len() as u32,
)
};
check(rc, "wc_AesXtsDecrypt")?;
Ok(())
}
}