use digest_trait::{FixedOutput, KeyInit, OutputSizeUser, Update};
use generic_array::GenericArray;
use typenum::{U16, U32};
use crate::error::len_as_u32;
#[cfg(wolfssl_poly1305)]
pub struct WolfPoly1305 {
ctx: wolfcrypt_rs::poly1305_state,
}
#[cfg(wolfssl_poly1305)]
unsafe impl Send for WolfPoly1305 {}
#[cfg(wolfssl_poly1305)]
impl Drop for WolfPoly1305 {
fn drop(&mut self) {
use zeroize::Zeroize;
let bytes = unsafe {
core::slice::from_raw_parts_mut(
&mut self.ctx as *mut wolfcrypt_rs::poly1305_state as *mut u8,
core::mem::size_of_val(&self.ctx),
)
};
bytes.zeroize();
}
}
#[cfg(wolfssl_poly1305)]
impl OutputSizeUser for WolfPoly1305 {
type OutputSize = U16; }
#[cfg(wolfssl_poly1305)]
impl crypto_common::KeySizeUser for WolfPoly1305 {
type KeySize = U32; }
#[cfg(wolfssl_poly1305)]
impl KeyInit for WolfPoly1305 {
fn new(key: &GenericArray<u8, U32>) -> Self {
let mut ctx = wolfcrypt_rs::poly1305_state::zeroed();
let rc = unsafe {
wolfcrypt_rs::wc_Poly1305SetKey(
&mut ctx as *mut wolfcrypt_rs::poly1305_state,
key.as_ptr(),
32,
)
};
assert_eq!(rc, 0, "wc_Poly1305SetKey failed (invalid key)");
Self { ctx }
}
fn new_from_slice(key: &[u8]) -> Result<Self, crypto_common::InvalidLength> {
if key.len() != 32 {
return Err(crypto_common::InvalidLength);
}
Ok(Self::new(GenericArray::from_slice(key)))
}
}
#[cfg(wolfssl_poly1305)]
impl Update for WolfPoly1305 {
fn update(&mut self, data: &[u8]) {
let rc = unsafe {
wolfcrypt_rs::wc_Poly1305Update(
&mut self.ctx as *mut wolfcrypt_rs::poly1305_state,
data.as_ptr(),
len_as_u32(data.len()),
)
};
assert_eq!(rc, 0, "wc_Poly1305Update failed (context not initialized)");
}
}
#[cfg(wolfssl_poly1305)]
impl FixedOutput for WolfPoly1305 {
fn finalize_into(mut self, out: &mut GenericArray<u8, Self::OutputSize>) {
let rc = unsafe {
wolfcrypt_rs::wc_Poly1305Final(
&mut self.ctx as *mut wolfcrypt_rs::poly1305_state,
out.as_mut_ptr(),
)
};
assert_eq!(rc, 0, "wc_Poly1305Final failed (context not initialized)");
}
}
#[cfg(wolfssl_poly1305)]
impl digest_trait::MacMarker for WolfPoly1305 {}