#![cfg(aes)]
use crate::sys;
use core::mem::MaybeUninit;
use zeroize::{Zeroize, ZeroizeOnDrop};
#[cfg(feature = "aead")]
use aead::{AeadCore, AeadInPlace, KeyInit, KeySizeUser};
#[cfg(feature = "aead")]
use aead::generic_array::typenum::{U0, U12, U16, U24, U32};
#[cfg(all(feature = "cipher", not(feature = "aead")))]
use cipher::typenum::consts::{U16, U24, U32};
#[cfg(feature = "cipher")]
use cipher::{
BlockModeDecBackend, BlockModeDecClosure, BlockModeDecrypt,
BlockModeEncBackend, BlockModeEncClosure, BlockModeEncrypt,
IvSizeUser, KeyIvInit, ParBlocksSizeUser,
};
#[cfg(all(any(aes_ctr, aes_ofb), feature = "cipher"))]
use cipher::{StreamCipher,StreamCipherError};
#[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 = crate::buffer_len_to_u32(key.len())?;
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(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesCbcEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesCbcDecrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_cbc)]
impl CBC {
fn zeroize(&mut self) {
unsafe { crate::zeroize_raw(&mut self.ws_aes); }
}
}
#[cfg(aes_cbc)]
impl Drop for CBC {
fn drop(&mut self) {
unsafe { sys::wc_AesFree(&mut self.ws_aes); }
self.zeroize();
}
}
#[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 = crate::buffer_len_to_u32(key.len())?;
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(&mut self, din: &[u8], dout: &mut [u8], nonce: &[u8], auth: &[u8], auth_tag: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
let nonce_size = crate::buffer_len_to_u32(nonce.len())?;
let auth_size = crate::buffer_len_to_u32(auth.len())?;
let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesCcmEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_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(&mut self, din: &[u8], dout: &mut [u8], nonce: &[u8], auth: &[u8], auth_tag: &[u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
let nonce_size = crate::buffer_len_to_u32(nonce.len())?;
let auth_size = crate::buffer_len_to_u32(auth.len())?;
let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesCcmDecrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_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_ccm)]
impl CCM {
fn zeroize(&mut self) {
unsafe { crate::zeroize_raw(&mut self.ws_aes); }
}
}
#[cfg(aes_ccm)]
impl Drop for CCM {
fn drop(&mut self) {
unsafe { sys::wc_AesFree(&mut self.ws_aes); }
self.zeroize();
}
}
#[cfg(all(aes_ccm, feature = "aead"))]
fn ccm_encrypt_in_place(
key: &[u8],
nonce: &[u8],
aad: &[u8],
buffer: &mut [u8],
tag: &mut [u8],
) -> Result<(), aead::Error> {
if buffer.len() > u32::MAX as usize || nonce.len() > u32::MAX as usize
|| tag.len() > u32::MAX as usize || aad.len() > u32::MAX as usize {
return Err(aead::Error);
}
let mut ccm = CCM::new().map_err(|_| aead::Error)?;
ccm.init(key).map_err(|_| aead::Error)?;
let buf_ptr = buffer.as_mut_ptr();
let in_ptr = buf_ptr as *const u8;
let rc = unsafe {
sys::wc_AesCcmEncrypt(
&mut ccm.ws_aes,
buf_ptr, in_ptr, buffer.len() as u32,
nonce.as_ptr(), nonce.len() as u32,
tag.as_mut_ptr(), tag.len() as u32,
aad.as_ptr(), aad.len() as u32,
)
};
if rc != 0 {
return Err(aead::Error);
}
Ok(())
}
#[cfg(all(aes_ccm, feature = "aead"))]
fn ccm_decrypt_in_place(
key: &[u8],
nonce: &[u8],
aad: &[u8],
buffer: &mut [u8],
tag: &[u8],
) -> Result<(), aead::Error> {
if buffer.len() > u32::MAX as usize || nonce.len() > u32::MAX as usize
|| tag.len() > u32::MAX as usize || aad.len() > u32::MAX as usize {
return Err(aead::Error);
}
let mut ccm = CCM::new().map_err(|_| aead::Error)?;
ccm.init(key).map_err(|_| aead::Error)?;
let buf_ptr = buffer.as_mut_ptr();
let in_ptr = buf_ptr as *const u8;
let rc = unsafe {
sys::wc_AesCcmDecrypt(
&mut ccm.ws_aes,
buf_ptr, in_ptr, buffer.len() as u32,
nonce.as_ptr(), nonce.len() as u32,
tag.as_ptr(), tag.len() as u32,
aad.as_ptr(), aad.len() as u32,
)
};
if rc != 0 {
return Err(aead::Error);
}
Ok(())
}
#[cfg(all(aes_ccm, feature = "aead"))]
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct Aes128Ccm {
key: [u8; 16],
}
#[cfg(all(aes_ccm, feature = "aead"))]
impl KeySizeUser for Aes128Ccm {
type KeySize = U16;
}
#[cfg(all(aes_ccm, feature = "aead"))]
impl AeadCore for Aes128Ccm {
type NonceSize = U12;
type TagSize = U16;
type CiphertextOverhead = U0;
}
#[cfg(all(aes_ccm, feature = "aead"))]
impl KeyInit for Aes128Ccm {
fn new(key: &aead::Key<Self>) -> Self {
let mut k = [0u8; 16];
k.copy_from_slice(key.as_ref());
Aes128Ccm { key: k }
}
}
#[cfg(all(aes_ccm, feature = "aead"))]
impl AeadInPlace for Aes128Ccm {
fn encrypt_in_place_detached(
&self,
nonce: &aead::Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
) -> Result<aead::Tag<Self>, aead::Error> {
let mut tag = aead::Tag::<Self>::default();
ccm_encrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_mut())?;
Ok(tag)
}
fn decrypt_in_place_detached(
&self,
nonce: &aead::Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
tag: &aead::Tag<Self>,
) -> Result<(), aead::Error> {
ccm_decrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_ref())
}
}
#[cfg(all(aes_ccm, feature = "aead"))]
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct Aes192Ccm {
key: [u8; 24],
}
#[cfg(all(aes_ccm, feature = "aead"))]
impl KeySizeUser for Aes192Ccm {
type KeySize = U24;
}
#[cfg(all(aes_ccm, feature = "aead"))]
impl AeadCore for Aes192Ccm {
type NonceSize = U12;
type TagSize = U16;
type CiphertextOverhead = U0;
}
#[cfg(all(aes_ccm, feature = "aead"))]
impl KeyInit for Aes192Ccm {
fn new(key: &aead::Key<Self>) -> Self {
let mut k = [0u8; 24];
k.copy_from_slice(key.as_ref());
Aes192Ccm { key: k }
}
}
#[cfg(all(aes_ccm, feature = "aead"))]
impl AeadInPlace for Aes192Ccm {
fn encrypt_in_place_detached(
&self,
nonce: &aead::Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
) -> Result<aead::Tag<Self>, aead::Error> {
let mut tag = aead::Tag::<Self>::default();
ccm_encrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_mut())?;
Ok(tag)
}
fn decrypt_in_place_detached(
&self,
nonce: &aead::Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
tag: &aead::Tag<Self>,
) -> Result<(), aead::Error> {
ccm_decrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_ref())
}
}
#[cfg(all(aes_ccm, feature = "aead"))]
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct Aes256Ccm {
key: [u8; 32],
}
#[cfg(all(aes_ccm, feature = "aead"))]
impl KeySizeUser for Aes256Ccm {
type KeySize = U32;
}
#[cfg(all(aes_ccm, feature = "aead"))]
impl AeadCore for Aes256Ccm {
type NonceSize = U12;
type TagSize = U16;
type CiphertextOverhead = U0;
}
#[cfg(all(aes_ccm, feature = "aead"))]
impl KeyInit for Aes256Ccm {
fn new(key: &aead::Key<Self>) -> Self {
let mut k = [0u8; 32];
k.copy_from_slice(key.as_ref());
Aes256Ccm { key: k }
}
}
#[cfg(all(aes_ccm, feature = "aead"))]
impl AeadInPlace for Aes256Ccm {
fn encrypt_in_place_detached(
&self,
nonce: &aead::Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
) -> Result<aead::Tag<Self>, aead::Error> {
let mut tag = aead::Tag::<Self>::default();
ccm_encrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_mut())?;
Ok(tag)
}
fn decrypt_in_place_detached(
&self,
nonce: &aead::Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
tag: &aead::Tag<Self>,
) -> Result<(), aead::Error> {
ccm_decrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_ref())
}
}
#[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 = crate::buffer_len_to_u32(key.len())?;
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(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesCfbEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt1(&mut self, din: &[u8], dout: &mut [u8], size: usize) -> Result<(), i32> {
if din.len() != dout.len() {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
if din.len() < size.div_ceil(8) {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let bit_size = crate::buffer_len_to_u32(size)?;
let rc = unsafe {
sys::wc_AesCfb1Encrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), bit_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt8(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesCfb8Encrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
#[cfg(aes_decrypt)]
pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesCfbDecrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
#[cfg(aes_decrypt)]
pub fn decrypt1(&mut self, din: &[u8], dout: &mut [u8], size: usize) -> Result<(), i32> {
if din.len() != dout.len() {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
if din.len() < size.div_ceil(8) {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let bit_size = crate::buffer_len_to_u32(size)?;
let rc = unsafe {
sys::wc_AesCfb1Decrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), bit_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
#[cfg(aes_decrypt)]
pub fn decrypt8(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesCfb8Decrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_cfb)]
impl CFB {
fn zeroize(&mut self) {
unsafe { crate::zeroize_raw(&mut self.ws_aes); }
}
}
#[cfg(aes_cfb)]
impl Drop for CFB {
fn drop(&mut self) {
unsafe { sys::wc_AesFree(&mut self.ws_aes); }
self.zeroize();
}
}
#[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 = crate::buffer_len_to_u32(key.len())?;
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(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesCtrEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
self.encrypt_decrypt(din, dout)
}
pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
self.encrypt_decrypt(din, dout)
}
}
#[cfg(aes_ctr)]
impl CTR {
fn zeroize(&mut self) {
unsafe { crate::zeroize_raw(&mut self.ws_aes); }
}
}
#[cfg(aes_ctr)]
impl Drop for CTR {
fn drop(&mut self) {
unsafe { sys::wc_AesFree(&mut self.ws_aes); }
self.zeroize();
}
}
#[cfg(aes_eax)]
pub struct EAX {
}
#[cfg(aes_eax)]
impl EAX {
pub fn encrypt(din: &[u8], dout: &mut [u8], key: &[u8], nonce: &[u8],
auth: &[u8], auth_tag: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
let key_size = crate::buffer_len_to_u32(key.len())?;
let nonce_size = crate::buffer_len_to_u32(nonce.len())?;
let auth_size = crate::buffer_len_to_u32(auth.len())?;
let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesEaxEncryptAuth(key.as_ptr(), key_size, dout.as_mut_ptr(),
din.as_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(din: &[u8], dout: &mut [u8], key: &[u8], nonce: &[u8],
auth: &[u8], auth_tag: &[u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
let key_size = crate::buffer_len_to_u32(key.len())?;
let nonce_size = crate::buffer_len_to_u32(nonce.len())?;
let auth_size = crate::buffer_len_to_u32(auth.len())?;
let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesEaxDecryptAuth(key.as_ptr(), key_size, dout.as_mut_ptr(),
din.as_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 = crate::buffer_len_to_u32(key.len())?;
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(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesEcbEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesEcbDecrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_ecb)]
impl ECB {
fn zeroize(&mut self) {
unsafe { crate::zeroize_raw(&mut self.ws_aes); }
}
}
#[cfg(aes_ecb)]
impl Drop for ECB {
fn drop(&mut self) {
unsafe { sys::wc_AesFree(&mut self.ws_aes); }
self.zeroize();
}
}
#[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 = crate::buffer_len_to_u32(key.len())?;
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(&mut self, din: &[u8], dout: &mut [u8], iv: &[u8],
auth: &[u8], auth_tag: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
let iv_size = crate::buffer_len_to_u32(iv.len())?;
let auth_size = crate::buffer_len_to_u32(auth.len())?;
let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesGcmEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_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(&mut self, din: &[u8], dout: &mut [u8], iv: &[u8],
auth: &[u8], auth_tag: &[u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
let iv_size = crate::buffer_len_to_u32(iv.len())?;
let auth_size = crate::buffer_len_to_u32(auth.len())?;
let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesGcmDecrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_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 GCM {
fn zeroize(&mut self) {
unsafe { crate::zeroize_raw(&mut self.ws_aes); }
}
}
#[cfg(aes_gcm)]
impl Drop for GCM {
fn drop(&mut self) {
unsafe { sys::wc_AesFree(&mut self.ws_aes); }
self.zeroize();
}
}
#[cfg(all(aes_gcm, feature = "aead"))]
fn gcm_encrypt_in_place(
key: &[u8],
nonce: &[u8],
aad: &[u8],
buffer: &mut [u8],
tag: &mut [u8],
) -> Result<(), aead::Error> {
if buffer.len() > u32::MAX as usize || nonce.len() > u32::MAX as usize
|| tag.len() > u32::MAX as usize || aad.len() > u32::MAX as usize {
return Err(aead::Error);
}
let mut gcm = GCM::new().map_err(|_| aead::Error)?;
gcm.init(key).map_err(|_| aead::Error)?;
let buf_ptr = buffer.as_mut_ptr();
let in_ptr = buf_ptr as *const u8;
let rc = unsafe {
sys::wc_AesGcmEncrypt(
&mut gcm.ws_aes,
buf_ptr, in_ptr, buffer.len() as u32,
nonce.as_ptr(), nonce.len() as u32,
tag.as_mut_ptr(), tag.len() as u32,
aad.as_ptr(), aad.len() as u32,
)
};
if rc != 0 {
return Err(aead::Error);
}
Ok(())
}
#[cfg(all(aes_gcm, feature = "aead"))]
fn gcm_decrypt_in_place(
key: &[u8],
nonce: &[u8],
aad: &[u8],
buffer: &mut [u8],
tag: &[u8],
) -> Result<(), aead::Error> {
if buffer.len() > u32::MAX as usize || nonce.len() > u32::MAX as usize
|| tag.len() > u32::MAX as usize || aad.len() > u32::MAX as usize {
return Err(aead::Error);
}
let mut gcm = GCM::new().map_err(|_| aead::Error)?;
gcm.init(key).map_err(|_| aead::Error)?;
let buf_ptr = buffer.as_mut_ptr();
let in_ptr = buf_ptr as *const u8;
let rc = unsafe {
sys::wc_AesGcmDecrypt(
&mut gcm.ws_aes,
buf_ptr, in_ptr, buffer.len() as u32,
nonce.as_ptr(), nonce.len() as u32,
tag.as_ptr(), tag.len() as u32,
aad.as_ptr(), aad.len() as u32,
)
};
if rc != 0 {
return Err(aead::Error);
}
Ok(())
}
#[cfg(all(aes_gcm, feature = "aead"))]
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct Aes128Gcm {
key: [u8; 16],
}
#[cfg(all(aes_gcm, feature = "aead"))]
impl KeySizeUser for Aes128Gcm {
type KeySize = U16;
}
#[cfg(all(aes_gcm, feature = "aead"))]
impl AeadCore for Aes128Gcm {
type NonceSize = U12;
type TagSize = U16;
type CiphertextOverhead = U0;
}
#[cfg(all(aes_gcm, feature = "aead"))]
impl KeyInit for Aes128Gcm {
fn new(key: &aead::Key<Self>) -> Self {
let mut k = [0u8; 16];
k.copy_from_slice(key.as_ref());
Aes128Gcm { key: k }
}
}
#[cfg(all(aes_gcm, feature = "aead"))]
impl AeadInPlace for Aes128Gcm {
fn encrypt_in_place_detached(
&self,
nonce: &aead::Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
) -> Result<aead::Tag<Self>, aead::Error> {
let mut tag = aead::Tag::<Self>::default();
gcm_encrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_mut())?;
Ok(tag)
}
fn decrypt_in_place_detached(
&self,
nonce: &aead::Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
tag: &aead::Tag<Self>,
) -> Result<(), aead::Error> {
gcm_decrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_ref())
}
}
#[cfg(all(aes_gcm, feature = "aead"))]
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct Aes192Gcm {
key: [u8; 24],
}
#[cfg(all(aes_gcm, feature = "aead"))]
impl KeySizeUser for Aes192Gcm {
type KeySize = U24;
}
#[cfg(all(aes_gcm, feature = "aead"))]
impl AeadCore for Aes192Gcm {
type NonceSize = U12;
type TagSize = U16;
type CiphertextOverhead = U0;
}
#[cfg(all(aes_gcm, feature = "aead"))]
impl KeyInit for Aes192Gcm {
fn new(key: &aead::Key<Self>) -> Self {
let mut k = [0u8; 24];
k.copy_from_slice(key.as_ref());
Aes192Gcm { key: k }
}
}
#[cfg(all(aes_gcm, feature = "aead"))]
impl AeadInPlace for Aes192Gcm {
fn encrypt_in_place_detached(
&self,
nonce: &aead::Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
) -> Result<aead::Tag<Self>, aead::Error> {
let mut tag = aead::Tag::<Self>::default();
gcm_encrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_mut())?;
Ok(tag)
}
fn decrypt_in_place_detached(
&self,
nonce: &aead::Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
tag: &aead::Tag<Self>,
) -> Result<(), aead::Error> {
gcm_decrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_ref())
}
}
#[cfg(all(aes_gcm, feature = "aead"))]
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct Aes256Gcm {
key: [u8; 32],
}
#[cfg(all(aes_gcm, feature = "aead"))]
impl KeySizeUser for Aes256Gcm {
type KeySize = U32;
}
#[cfg(all(aes_gcm, feature = "aead"))]
impl AeadCore for Aes256Gcm {
type NonceSize = U12;
type TagSize = U16;
type CiphertextOverhead = U0;
}
#[cfg(all(aes_gcm, feature = "aead"))]
impl KeyInit for Aes256Gcm {
fn new(key: &aead::Key<Self>) -> Self {
let mut k = [0u8; 32];
k.copy_from_slice(key.as_ref());
Aes256Gcm { key: k }
}
}
#[cfg(all(aes_gcm, feature = "aead"))]
impl AeadInPlace for Aes256Gcm {
fn encrypt_in_place_detached(
&self,
nonce: &aead::Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
) -> Result<aead::Tag<Self>, aead::Error> {
let mut tag = aead::Tag::<Self>::default();
gcm_encrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_mut())?;
Ok(tag)
}
fn decrypt_in_place_detached(
&self,
nonce: &aead::Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
tag: &aead::Tag<Self>,
) -> Result<(), aead::Error> {
gcm_decrypt_in_place(&self.key, nonce.as_ref(), associated_data, buffer, tag.as_ref())
}
}
#[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 = crate::buffer_len_to_u32(key.len())?;
let iv_size = crate::buffer_len_to_u32(iv.len())?;
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(&mut self, din: &[u8], dout: &mut [u8],
auth: &[u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
let auth_size = crate::buffer_len_to_u32(auth.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesGcmEncryptUpdate(&mut self.ws_aes, dout.as_mut_ptr(),
din.as_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 = crate::buffer_len_to_u32(auth_tag.len())?;
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(&mut self, din: &[u8], dout: &mut [u8],
auth: &[u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
let auth_size = crate::buffer_len_to_u32(auth.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesGcmDecryptUpdate(&mut self.ws_aes, dout.as_mut_ptr(),
din.as_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 = crate::buffer_len_to_u32(auth_tag.len())?;
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 GCMStream {
fn zeroize(&mut self) {
unsafe { crate::zeroize_raw(&mut self.ws_aes); }
}
}
#[cfg(aes_gcm_stream)]
impl Drop for GCMStream {
fn drop(&mut self) {
unsafe { sys::wc_AesFree(&mut self.ws_aes); }
self.zeroize();
}
}
#[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 = crate::buffer_len_to_u32(key.len())?;
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(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesOfbEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
#[cfg(aes_decrypt)]
pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesOfbDecrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_ofb)]
impl OFB {
fn zeroize(&mut self) {
unsafe { crate::zeroize_raw(&mut self.ws_aes); }
}
}
#[cfg(aes_ofb)]
impl Drop for OFB {
fn drop(&mut self) {
unsafe { sys::wc_AesFree(&mut self.ws_aes); }
self.zeroize();
}
}
#[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 = crate::buffer_len_to_u32(key.len())?;
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(&mut self, din: &[u8], dout: &mut [u8], tweak: &[u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
let tweak_size = crate::buffer_len_to_u32(tweak.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsEncrypt(&mut self.ws_xtsaes, dout.as_mut_ptr(),
din.as_ptr(), in_size, tweak.as_ptr(), tweak_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt_sector(&mut self, din: &[u8], dout: &mut [u8], sector: u64) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsEncryptSector(&mut self.ws_xtsaes, dout.as_mut_ptr(),
din.as_ptr(), in_size, sector)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt_consecutive_sectors(&mut self, din: &[u8], dout: &mut [u8],
sector: u64, sector_size: u32) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsEncryptConsecutiveSectors(&mut self.ws_xtsaes,
dout.as_mut_ptr(), din.as_ptr(), in_size, sector, sector_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8], tweak: &[u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
let tweak_size = crate::buffer_len_to_u32(tweak.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsDecrypt(&mut self.ws_xtsaes, dout.as_mut_ptr(),
din.as_ptr(), in_size, tweak.as_ptr(), tweak_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt_sector(&mut self, din: &[u8], dout: &mut [u8], sector: u64) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsDecryptSector(&mut self.ws_xtsaes, dout.as_mut_ptr(),
din.as_ptr(), in_size, sector)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt_consecutive_sectors(&mut self, din: &[u8], dout: &mut [u8],
sector: u64, sector_size: u32) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsDecryptConsecutiveSectors(&mut self.ws_xtsaes,
dout.as_mut_ptr(), din.as_ptr(), in_size, sector, sector_size)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_xts)]
impl XTS {
fn zeroize(&mut self) {
unsafe { crate::zeroize_raw(&mut self.ws_xtsaes); }
}
}
#[cfg(aes_xts)]
impl Drop for XTS {
fn drop(&mut self) {
unsafe { sys::wc_AesXtsFree(&mut self.ws_xtsaes); }
self.zeroize();
}
}
#[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::zeroed();
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 = crate::buffer_len_to_u32(key.len())?;
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 = crate::buffer_len_to_u32(tweak.len())?;
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 = crate::buffer_len_to_u32(key.len())?;
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 = crate::buffer_len_to_u32(tweak.len())?;
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(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsEncryptUpdate(&mut self.ws_xtsaes, dout.as_mut_ptr(),
din.as_ptr(), in_size, &mut self.ws_xtsaesstreamdata)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn encrypt_final(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsEncryptFinal(&mut self.ws_xtsaes, dout.as_mut_ptr(),
din.as_ptr(), in_size, &mut self.ws_xtsaesstreamdata)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt_update(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsDecryptUpdate(&mut self.ws_xtsaes, dout.as_mut_ptr(),
din.as_ptr(), in_size, &mut self.ws_xtsaesstreamdata)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn decrypt_final(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> {
let in_size = crate::buffer_len_to_u32(din.len())?;
let out_size = crate::buffer_len_to_u32(dout.len())?;
if in_size != out_size {
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
}
let rc = unsafe {
sys::wc_AesXtsDecryptFinal(&mut self.ws_xtsaes, dout.as_mut_ptr(),
din.as_ptr(), in_size, &mut self.ws_xtsaesstreamdata)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(aes_xts_stream)]
impl XTSStream {
fn zeroize(&mut self) {
unsafe {
crate::zeroize_raw(&mut self.ws_xtsaes);
crate::zeroize_raw(&mut self.ws_xtsaesstreamdata);
}
}
}
#[cfg(aes_xts_stream)]
impl Drop for XTSStream {
fn drop(&mut self) {
unsafe { sys::wc_AesXtsFree(&mut self.ws_xtsaes); }
self.zeroize();
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
pub struct Aes128EcbEnc {
inner: ECB,
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::KeySizeUser for Aes128EcbEnc {
type KeySize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes128EcbEnc {
type BlockSize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::KeyInit for Aes128EcbEnc {
fn new(key: &cipher::Key<Self>) -> Self {
let mut ecb = ECB::new().expect("wc_AesInit failed");
ecb.init_encrypt(key.as_ref()).expect("wc_AesSetKey failed");
Self { inner: ecb }
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
struct Aes128EcbEncBackend<'a>(&'a mut Aes128EcbEnc);
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes128EcbEncBackend<'_> {
type BlockSize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl ParBlocksSizeUser for Aes128EcbEncBackend<'_> {
type ParBlocksSize = cipher::typenum::consts::U1;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl BlockModeEncBackend for Aes128EcbEncBackend<'_> {
fn encrypt_block(&mut self, mut block: cipher::InOut<'_, '_, cipher::Block<Self>>) {
let in_block = *block.get_in();
let out = block.get_out();
self.0.inner.encrypt(in_block.as_ref(), out.as_mut()).expect("wc_AesEcbEncrypt failed");
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl BlockModeEncrypt for Aes128EcbEnc {
fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure<BlockSize = Self::BlockSize>) {
f.call(&mut Aes128EcbEncBackend(self));
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
pub struct Aes192EcbEnc {
inner: ECB,
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::KeySizeUser for Aes192EcbEnc {
type KeySize = U24;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes192EcbEnc {
type BlockSize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::KeyInit for Aes192EcbEnc {
fn new(key: &cipher::Key<Self>) -> Self {
let mut ecb = ECB::new().expect("wc_AesInit failed");
ecb.init_encrypt(key.as_ref()).expect("wc_AesSetKey failed");
Self { inner: ecb }
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
struct Aes192EcbEncBackend<'a>(&'a mut Aes192EcbEnc);
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes192EcbEncBackend<'_> {
type BlockSize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl ParBlocksSizeUser for Aes192EcbEncBackend<'_> {
type ParBlocksSize = cipher::typenum::consts::U1;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl BlockModeEncBackend for Aes192EcbEncBackend<'_> {
fn encrypt_block(&mut self, mut block: cipher::InOut<'_, '_, cipher::Block<Self>>) {
let in_block = *block.get_in();
let out = block.get_out();
self.0.inner.encrypt(in_block.as_ref(), out.as_mut()).expect("wc_AesEcbEncrypt failed");
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl BlockModeEncrypt for Aes192EcbEnc {
fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure<BlockSize = Self::BlockSize>) {
f.call(&mut Aes192EcbEncBackend(self));
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
pub struct Aes256EcbEnc {
inner: ECB,
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::KeySizeUser for Aes256EcbEnc {
type KeySize = U32;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes256EcbEnc {
type BlockSize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::KeyInit for Aes256EcbEnc {
fn new(key: &cipher::Key<Self>) -> Self {
let mut ecb = ECB::new().expect("wc_AesInit failed");
ecb.init_encrypt(key.as_ref()).expect("wc_AesSetKey failed");
Self { inner: ecb }
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
struct Aes256EcbEncBackend<'a>(&'a mut Aes256EcbEnc);
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes256EcbEncBackend<'_> {
type BlockSize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl ParBlocksSizeUser for Aes256EcbEncBackend<'_> {
type ParBlocksSize = cipher::typenum::consts::U1;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl BlockModeEncBackend for Aes256EcbEncBackend<'_> {
fn encrypt_block(&mut self, mut block: cipher::InOut<'_, '_, cipher::Block<Self>>) {
let in_block = *block.get_in();
let out = block.get_out();
self.0.inner.encrypt(in_block.as_ref(), out.as_mut()).expect("wc_AesEcbEncrypt failed");
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl BlockModeEncrypt for Aes256EcbEnc {
fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure<BlockSize = Self::BlockSize>) {
f.call(&mut Aes256EcbEncBackend(self));
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
pub struct Aes128EcbDec {
inner: ECB,
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::KeySizeUser for Aes128EcbDec {
type KeySize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes128EcbDec {
type BlockSize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::KeyInit for Aes128EcbDec {
fn new(key: &cipher::Key<Self>) -> Self {
let mut ecb = ECB::new().expect("wc_AesInit failed");
ecb.init_decrypt(key.as_ref()).expect("wc_AesSetKey failed");
Self { inner: ecb }
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
struct Aes128EcbDecBackend<'a>(&'a mut Aes128EcbDec);
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes128EcbDecBackend<'_> {
type BlockSize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl ParBlocksSizeUser for Aes128EcbDecBackend<'_> {
type ParBlocksSize = cipher::typenum::consts::U1;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl BlockModeDecBackend for Aes128EcbDecBackend<'_> {
fn decrypt_block(&mut self, mut block: cipher::InOut<'_, '_, cipher::Block<Self>>) {
let in_block = *block.get_in();
let out = block.get_out();
self.0.inner.decrypt(in_block.as_ref(), out.as_mut()).expect("wc_AesEcbDecrypt failed");
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl BlockModeDecrypt for Aes128EcbDec {
fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure<BlockSize = Self::BlockSize>) {
f.call(&mut Aes128EcbDecBackend(self));
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
pub struct Aes192EcbDec {
inner: ECB,
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::KeySizeUser for Aes192EcbDec {
type KeySize = U24;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes192EcbDec {
type BlockSize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::KeyInit for Aes192EcbDec {
fn new(key: &cipher::Key<Self>) -> Self {
let mut ecb = ECB::new().expect("wc_AesInit failed");
ecb.init_decrypt(key.as_ref()).expect("wc_AesSetKey failed");
Self { inner: ecb }
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
struct Aes192EcbDecBackend<'a>(&'a mut Aes192EcbDec);
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes192EcbDecBackend<'_> {
type BlockSize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl ParBlocksSizeUser for Aes192EcbDecBackend<'_> {
type ParBlocksSize = cipher::typenum::consts::U1;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl BlockModeDecBackend for Aes192EcbDecBackend<'_> {
fn decrypt_block(&mut self, mut block: cipher::InOut<'_, '_, cipher::Block<Self>>) {
let in_block = *block.get_in();
let out = block.get_out();
self.0.inner.decrypt(in_block.as_ref(), out.as_mut()).expect("wc_AesEcbDecrypt failed");
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl BlockModeDecrypt for Aes192EcbDec {
fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure<BlockSize = Self::BlockSize>) {
f.call(&mut Aes192EcbDecBackend(self));
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
pub struct Aes256EcbDec {
inner: ECB,
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::KeySizeUser for Aes256EcbDec {
type KeySize = U32;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes256EcbDec {
type BlockSize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::KeyInit for Aes256EcbDec {
fn new(key: &cipher::Key<Self>) -> Self {
let mut ecb = ECB::new().expect("wc_AesInit failed");
ecb.init_decrypt(key.as_ref()).expect("wc_AesSetKey failed");
Self { inner: ecb }
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
struct Aes256EcbDecBackend<'a>(&'a mut Aes256EcbDec);
#[cfg(all(aes_ecb, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes256EcbDecBackend<'_> {
type BlockSize = U16;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl ParBlocksSizeUser for Aes256EcbDecBackend<'_> {
type ParBlocksSize = cipher::typenum::consts::U1;
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl BlockModeDecBackend for Aes256EcbDecBackend<'_> {
fn decrypt_block(&mut self, mut block: cipher::InOut<'_, '_, cipher::Block<Self>>) {
let in_block = *block.get_in();
let out = block.get_out();
self.0.inner.decrypt(in_block.as_ref(), out.as_mut()).expect("wc_AesEcbDecrypt failed");
}
}
#[cfg(all(aes_ecb, feature = "cipher"))]
impl BlockModeDecrypt for Aes256EcbDec {
fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure<BlockSize = Self::BlockSize>) {
f.call(&mut Aes256EcbDecBackend(self));
}
}
#[cfg(all(aes_ctr, feature = "cipher"))]
pub struct Aes128Ctr {
inner: CTR,
}
#[cfg(all(aes_ctr, feature = "cipher"))]
impl cipher::KeySizeUser for Aes128Ctr {
type KeySize = U16;
}
#[cfg(all(aes_ctr, feature = "cipher"))]
impl IvSizeUser for Aes128Ctr {
type IvSize = U16;
}
#[cfg(all(aes_ctr, feature = "cipher"))]
impl KeyIvInit for Aes128Ctr {
fn new(key: &cipher::Key<Self>, iv: &cipher::Iv<Self>) -> Self {
let mut ctr = CTR::new().expect("wc_AesInit failed");
ctr.init(key.as_ref(), iv.as_ref()).expect("wc_AesSetKeyDirect failed");
Self { inner: ctr }
}
}
#[cfg(all(aes_ctr, feature = "cipher"))]
impl StreamCipher for Aes128Ctr {
fn check_remaining(&self, _data_len: usize) -> Result<(), StreamCipherError> {
Ok(())
}
fn unchecked_apply_keystream_inout(&mut self, mut buf: cipher::InOutBuf<'_, '_, u8>) {
let len = buf.len();
if len == 0 { return; }
assert!(len <= u32::MAX as usize, "buffer too large for wc_AesCtrEncrypt");
let in_ptr = buf.get_in().as_ptr();
let out_ptr = buf.get_out().as_mut_ptr();
let rc = unsafe { sys::wc_AesCtrEncrypt(&mut self.inner.ws_aes, out_ptr, in_ptr, len as u32) };
assert_eq!(rc, 0, "wc_AesCtrEncrypt failed");
}
fn unchecked_write_keystream(&mut self, buf: &mut [u8]) {
buf.fill(0);
self.unchecked_apply_keystream_inout(buf.into());
}
}
#[cfg(all(aes_ctr, feature = "cipher"))]
pub struct Aes192Ctr {
inner: CTR,
}
#[cfg(all(aes_ctr, feature = "cipher"))]
impl cipher::KeySizeUser for Aes192Ctr {
type KeySize = U24;
}
#[cfg(all(aes_ctr, feature = "cipher"))]
impl IvSizeUser for Aes192Ctr {
type IvSize = U16;
}
#[cfg(all(aes_ctr, feature = "cipher"))]
impl KeyIvInit for Aes192Ctr {
fn new(key: &cipher::Key<Self>, iv: &cipher::Iv<Self>) -> Self {
let mut ctr = CTR::new().expect("wc_AesInit failed");
ctr.init(key.as_ref(), iv.as_ref()).expect("wc_AesSetKeyDirect failed");
Self { inner: ctr }
}
}
#[cfg(all(aes_ctr, feature = "cipher"))]
impl StreamCipher for Aes192Ctr {
fn check_remaining(&self, _data_len: usize) -> Result<(), StreamCipherError> {
Ok(())
}
fn unchecked_apply_keystream_inout(&mut self, mut buf: cipher::InOutBuf<'_, '_, u8>) {
let len = buf.len();
if len == 0 { return; }
assert!(len <= u32::MAX as usize, "buffer too large for wc_AesCtrEncrypt");
let in_ptr = buf.get_in().as_ptr();
let out_ptr = buf.get_out().as_mut_ptr();
let rc = unsafe { sys::wc_AesCtrEncrypt(&mut self.inner.ws_aes, out_ptr, in_ptr, len as u32) };
assert_eq!(rc, 0, "wc_AesCtrEncrypt failed");
}
fn unchecked_write_keystream(&mut self, buf: &mut [u8]) {
buf.fill(0);
self.unchecked_apply_keystream_inout(buf.into());
}
}
#[cfg(all(aes_ctr, feature = "cipher"))]
pub struct Aes256Ctr {
inner: CTR,
}
#[cfg(all(aes_ctr, feature = "cipher"))]
impl cipher::KeySizeUser for Aes256Ctr {
type KeySize = U32;
}
#[cfg(all(aes_ctr, feature = "cipher"))]
impl IvSizeUser for Aes256Ctr {
type IvSize = U16;
}
#[cfg(all(aes_ctr, feature = "cipher"))]
impl KeyIvInit for Aes256Ctr {
fn new(key: &cipher::Key<Self>, iv: &cipher::Iv<Self>) -> Self {
let mut ctr = CTR::new().expect("wc_AesInit failed");
ctr.init(key.as_ref(), iv.as_ref()).expect("wc_AesSetKeyDirect failed");
Self { inner: ctr }
}
}
#[cfg(all(aes_ctr, feature = "cipher"))]
impl StreamCipher for Aes256Ctr {
fn check_remaining(&self, _data_len: usize) -> Result<(), StreamCipherError> {
Ok(())
}
fn unchecked_apply_keystream_inout(&mut self, mut buf: cipher::InOutBuf<'_, '_, u8>) {
let len = buf.len();
if len == 0 { return; }
assert!(len <= u32::MAX as usize, "buffer too large for wc_AesCtrEncrypt");
let in_ptr = buf.get_in().as_ptr();
let out_ptr = buf.get_out().as_mut_ptr();
let rc = unsafe { sys::wc_AesCtrEncrypt(&mut self.inner.ws_aes, out_ptr, in_ptr, len as u32) };
assert_eq!(rc, 0, "wc_AesCtrEncrypt failed");
}
fn unchecked_write_keystream(&mut self, buf: &mut [u8]) {
buf.fill(0);
self.unchecked_apply_keystream_inout(buf.into());
}
}
#[cfg(all(aes_ofb, feature = "cipher"))]
pub struct Aes128Ofb {
inner: OFB,
}
#[cfg(all(aes_ofb, feature = "cipher"))]
impl cipher::KeySizeUser for Aes128Ofb {
type KeySize = U16;
}
#[cfg(all(aes_ofb, feature = "cipher"))]
impl IvSizeUser for Aes128Ofb {
type IvSize = U16;
}
#[cfg(all(aes_ofb, feature = "cipher"))]
impl KeyIvInit for Aes128Ofb {
fn new(key: &cipher::Key<Self>, iv: &cipher::Iv<Self>) -> Self {
let mut ofb = OFB::new().expect("wc_AesInit failed");
ofb.init(key.as_ref(), iv.as_ref()).expect("wc_AesSetKey failed");
Self { inner: ofb }
}
}
#[cfg(all(aes_ofb, feature = "cipher"))]
impl StreamCipher for Aes128Ofb {
fn check_remaining(&self, _data_len: usize) -> Result<(), StreamCipherError> {
Ok(())
}
fn unchecked_apply_keystream_inout(&mut self, mut buf: cipher::InOutBuf<'_, '_, u8>) {
let len = buf.len();
if len == 0 { return; }
assert!(len <= u32::MAX as usize, "buffer too large for wc_AesOfbEncrypt");
let in_ptr = buf.get_in().as_ptr();
let out_ptr = buf.get_out().as_mut_ptr();
let rc = unsafe { sys::wc_AesOfbEncrypt(&mut self.inner.ws_aes, out_ptr, in_ptr, len as u32) };
assert_eq!(rc, 0, "wc_AesOfbEncrypt failed");
}
fn unchecked_write_keystream(&mut self, buf: &mut [u8]) {
buf.fill(0);
self.unchecked_apply_keystream_inout(buf.into());
}
}
#[cfg(all(aes_ofb, feature = "cipher"))]
pub struct Aes192Ofb {
inner: OFB,
}
#[cfg(all(aes_ofb, feature = "cipher"))]
impl cipher::KeySizeUser for Aes192Ofb {
type KeySize = U24;
}
#[cfg(all(aes_ofb, feature = "cipher"))]
impl IvSizeUser for Aes192Ofb {
type IvSize = U16;
}
#[cfg(all(aes_ofb, feature = "cipher"))]
impl KeyIvInit for Aes192Ofb {
fn new(key: &cipher::Key<Self>, iv: &cipher::Iv<Self>) -> Self {
let mut ofb = OFB::new().expect("wc_AesInit failed");
ofb.init(key.as_ref(), iv.as_ref()).expect("wc_AesSetKey failed");
Self { inner: ofb }
}
}
#[cfg(all(aes_ofb, feature = "cipher"))]
impl StreamCipher for Aes192Ofb {
fn check_remaining(&self, _data_len: usize) -> Result<(), StreamCipherError> {
Ok(())
}
fn unchecked_apply_keystream_inout(&mut self, mut buf: cipher::InOutBuf<'_, '_, u8>) {
let len = buf.len();
if len == 0 { return; }
assert!(len <= u32::MAX as usize, "buffer too large for wc_AesOfbEncrypt");
let in_ptr = buf.get_in().as_ptr();
let out_ptr = buf.get_out().as_mut_ptr();
let rc = unsafe { sys::wc_AesOfbEncrypt(&mut self.inner.ws_aes, out_ptr, in_ptr, len as u32) };
assert_eq!(rc, 0, "wc_AesOfbEncrypt failed");
}
fn unchecked_write_keystream(&mut self, buf: &mut [u8]) {
buf.fill(0);
self.unchecked_apply_keystream_inout(buf.into());
}
}
#[cfg(all(aes_ofb, feature = "cipher"))]
pub struct Aes256Ofb {
inner: OFB,
}
#[cfg(all(aes_ofb, feature = "cipher"))]
impl cipher::KeySizeUser for Aes256Ofb {
type KeySize = U32;
}
#[cfg(all(aes_ofb, feature = "cipher"))]
impl IvSizeUser for Aes256Ofb {
type IvSize = U16;
}
#[cfg(all(aes_ofb, feature = "cipher"))]
impl KeyIvInit for Aes256Ofb {
fn new(key: &cipher::Key<Self>, iv: &cipher::Iv<Self>) -> Self {
let mut ofb = OFB::new().expect("wc_AesInit failed");
ofb.init(key.as_ref(), iv.as_ref()).expect("wc_AesSetKey failed");
Self { inner: ofb }
}
}
#[cfg(all(aes_ofb, feature = "cipher"))]
impl StreamCipher for Aes256Ofb {
fn check_remaining(&self, _data_len: usize) -> Result<(), StreamCipherError> {
Ok(())
}
fn unchecked_apply_keystream_inout(&mut self, mut buf: cipher::InOutBuf<'_, '_, u8>) {
let len = buf.len();
if len == 0 { return; }
assert!(len <= u32::MAX as usize, "buffer too large for wc_AesOfbEncrypt");
let in_ptr = buf.get_in().as_ptr();
let out_ptr = buf.get_out().as_mut_ptr();
let rc = unsafe { sys::wc_AesOfbEncrypt(&mut self.inner.ws_aes, out_ptr, in_ptr, len as u32) };
assert_eq!(rc, 0, "wc_AesOfbEncrypt failed");
}
fn unchecked_write_keystream(&mut self, buf: &mut [u8]) {
buf.fill(0);
self.unchecked_apply_keystream_inout(buf.into());
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
pub struct Aes128CbcEnc {
inner: CBC,
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::KeySizeUser for Aes128CbcEnc {
type KeySize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes128CbcEnc {
type BlockSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl IvSizeUser for Aes128CbcEnc {
type IvSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl KeyIvInit for Aes128CbcEnc {
fn new(key: &cipher::Key<Self>, iv: &cipher::Iv<Self>) -> Self {
let mut cbc = CBC::new().expect("wc_AesInit failed");
cbc.init_encrypt(key.as_ref(), iv.as_ref()).expect("wc_AesSetKey failed");
Self { inner: cbc }
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
struct Aes128CbcEncBackend<'a>(&'a mut Aes128CbcEnc);
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes128CbcEncBackend<'_> {
type BlockSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl ParBlocksSizeUser for Aes128CbcEncBackend<'_> {
type ParBlocksSize = cipher::typenum::consts::U1;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl BlockModeEncBackend for Aes128CbcEncBackend<'_> {
fn encrypt_block(&mut self, mut block: cipher::InOut<'_, '_, cipher::Block<Self>>) {
let in_block = *block.get_in();
let out = block.get_out();
self.0.inner.encrypt(in_block.as_ref(), out.as_mut()).expect("wc_AesCbcEncrypt failed");
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl BlockModeEncrypt for Aes128CbcEnc {
fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure<BlockSize = Self::BlockSize>) {
f.call(&mut Aes128CbcEncBackend(self));
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
pub struct Aes192CbcEnc {
inner: CBC,
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::KeySizeUser for Aes192CbcEnc {
type KeySize = U24;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes192CbcEnc {
type BlockSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl IvSizeUser for Aes192CbcEnc {
type IvSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl KeyIvInit for Aes192CbcEnc {
fn new(key: &cipher::Key<Self>, iv: &cipher::Iv<Self>) -> Self {
let mut cbc = CBC::new().expect("wc_AesInit failed");
cbc.init_encrypt(key.as_ref(), iv.as_ref()).expect("wc_AesSetKey failed");
Self { inner: cbc }
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
struct Aes192CbcEncBackend<'a>(&'a mut Aes192CbcEnc);
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes192CbcEncBackend<'_> {
type BlockSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl ParBlocksSizeUser for Aes192CbcEncBackend<'_> {
type ParBlocksSize = cipher::typenum::consts::U1;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl BlockModeEncBackend for Aes192CbcEncBackend<'_> {
fn encrypt_block(&mut self, mut block: cipher::InOut<'_, '_, cipher::Block<Self>>) {
let in_block = *block.get_in();
let out = block.get_out();
self.0.inner.encrypt(in_block.as_ref(), out.as_mut()).expect("wc_AesCbcEncrypt failed");
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl BlockModeEncrypt for Aes192CbcEnc {
fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure<BlockSize = Self::BlockSize>) {
f.call(&mut Aes192CbcEncBackend(self));
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
pub struct Aes256CbcEnc {
inner: CBC,
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::KeySizeUser for Aes256CbcEnc {
type KeySize = U32;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes256CbcEnc {
type BlockSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl IvSizeUser for Aes256CbcEnc {
type IvSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl KeyIvInit for Aes256CbcEnc {
fn new(key: &cipher::Key<Self>, iv: &cipher::Iv<Self>) -> Self {
let mut cbc = CBC::new().expect("wc_AesInit failed");
cbc.init_encrypt(key.as_ref(), iv.as_ref()).expect("wc_AesSetKey failed");
Self { inner: cbc }
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
struct Aes256CbcEncBackend<'a>(&'a mut Aes256CbcEnc);
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes256CbcEncBackend<'_> {
type BlockSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl ParBlocksSizeUser for Aes256CbcEncBackend<'_> {
type ParBlocksSize = cipher::typenum::consts::U1;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl BlockModeEncBackend for Aes256CbcEncBackend<'_> {
fn encrypt_block(&mut self, mut block: cipher::InOut<'_, '_, cipher::Block<Self>>) {
let in_block = *block.get_in();
let out = block.get_out();
self.0.inner.encrypt(in_block.as_ref(), out.as_mut()).expect("wc_AesCbcEncrypt failed");
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl BlockModeEncrypt for Aes256CbcEnc {
fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure<BlockSize = Self::BlockSize>) {
f.call(&mut Aes256CbcEncBackend(self));
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
pub struct Aes128CbcDec {
inner: CBC,
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::KeySizeUser for Aes128CbcDec {
type KeySize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes128CbcDec {
type BlockSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl IvSizeUser for Aes128CbcDec {
type IvSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl KeyIvInit for Aes128CbcDec {
fn new(key: &cipher::Key<Self>, iv: &cipher::Iv<Self>) -> Self {
let mut cbc = CBC::new().expect("wc_AesInit failed");
cbc.init_decrypt(key.as_ref(), iv.as_ref()).expect("wc_AesSetKey failed");
Self { inner: cbc }
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
struct Aes128CbcDecBackend<'a>(&'a mut Aes128CbcDec);
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes128CbcDecBackend<'_> {
type BlockSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl ParBlocksSizeUser for Aes128CbcDecBackend<'_> {
type ParBlocksSize = cipher::typenum::consts::U1;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl BlockModeDecBackend for Aes128CbcDecBackend<'_> {
fn decrypt_block(&mut self, mut block: cipher::InOut<'_, '_, cipher::Block<Self>>) {
let in_block = *block.get_in();
let out = block.get_out();
self.0.inner.decrypt(in_block.as_ref(), out.as_mut()).expect("wc_AesCbcDecrypt failed");
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl BlockModeDecrypt for Aes128CbcDec {
fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure<BlockSize = Self::BlockSize>) {
f.call(&mut Aes128CbcDecBackend(self));
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
pub struct Aes192CbcDec {
inner: CBC,
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::KeySizeUser for Aes192CbcDec {
type KeySize = U24;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes192CbcDec {
type BlockSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl IvSizeUser for Aes192CbcDec {
type IvSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl KeyIvInit for Aes192CbcDec {
fn new(key: &cipher::Key<Self>, iv: &cipher::Iv<Self>) -> Self {
let mut cbc = CBC::new().expect("wc_AesInit failed");
cbc.init_decrypt(key.as_ref(), iv.as_ref()).expect("wc_AesSetKey failed");
Self { inner: cbc }
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
struct Aes192CbcDecBackend<'a>(&'a mut Aes192CbcDec);
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes192CbcDecBackend<'_> {
type BlockSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl ParBlocksSizeUser for Aes192CbcDecBackend<'_> {
type ParBlocksSize = cipher::typenum::consts::U1;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl BlockModeDecBackend for Aes192CbcDecBackend<'_> {
fn decrypt_block(&mut self, mut block: cipher::InOut<'_, '_, cipher::Block<Self>>) {
let in_block = *block.get_in();
let out = block.get_out();
self.0.inner.decrypt(in_block.as_ref(), out.as_mut()).expect("wc_AesCbcDecrypt failed");
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl BlockModeDecrypt for Aes192CbcDec {
fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure<BlockSize = Self::BlockSize>) {
f.call(&mut Aes192CbcDecBackend(self));
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
pub struct Aes256CbcDec {
inner: CBC,
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::KeySizeUser for Aes256CbcDec {
type KeySize = U32;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes256CbcDec {
type BlockSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl IvSizeUser for Aes256CbcDec {
type IvSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl KeyIvInit for Aes256CbcDec {
fn new(key: &cipher::Key<Self>, iv: &cipher::Iv<Self>) -> Self {
let mut cbc = CBC::new().expect("wc_AesInit failed");
cbc.init_decrypt(key.as_ref(), iv.as_ref()).expect("wc_AesSetKey failed");
Self { inner: cbc }
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
struct Aes256CbcDecBackend<'a>(&'a mut Aes256CbcDec);
#[cfg(all(aes_cbc, feature = "cipher"))]
impl cipher::BlockSizeUser for Aes256CbcDecBackend<'_> {
type BlockSize = U16;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl ParBlocksSizeUser for Aes256CbcDecBackend<'_> {
type ParBlocksSize = cipher::typenum::consts::U1;
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl BlockModeDecBackend for Aes256CbcDecBackend<'_> {
fn decrypt_block(&mut self, mut block: cipher::InOut<'_, '_, cipher::Block<Self>>) {
let in_block = *block.get_in();
let out = block.get_out();
self.0.inner.decrypt(in_block.as_ref(), out.as_mut()).expect("wc_AesCbcDecrypt failed");
}
}
#[cfg(all(aes_cbc, feature = "cipher"))]
impl BlockModeDecrypt for Aes256CbcDec {
fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure<BlockSize = Self::BlockSize>) {
f.call(&mut Aes256CbcDecBackend(self));
}
}
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)
}