#![cfg(any(blake2b, blake2s))]
use crate::sys;
use core::mem::MaybeUninit;
#[cfg(blake2b)]
pub struct BLAKE2b {
wc_blake2b: sys::Blake2b,
}
#[cfg(blake2b)]
impl BLAKE2b {
pub fn new(digest_size: usize) -> Result<Self, i32> {
let digest_size = digest_size as u32;
let mut wc_blake2b: MaybeUninit<sys::Blake2b> = MaybeUninit::uninit();
let rc = unsafe { sys::wc_InitBlake2b(wc_blake2b.as_mut_ptr(), digest_size) };
if rc != 0 {
return Err(rc);
}
let wc_blake2b = unsafe { wc_blake2b.assume_init() };
let blake2b = BLAKE2b { wc_blake2b };
Ok(blake2b)
}
pub fn new_with_key(digest_size: usize, key: &[u8]) -> Result<Self, i32> {
let digest_size = digest_size as u32;
let mut wc_blake2b: MaybeUninit<sys::Blake2b> = MaybeUninit::uninit();
let key_size = key.len() as u32;
let rc = unsafe {
sys::wc_InitBlake2b_WithKey(
wc_blake2b.as_mut_ptr(),
digest_size,
key.as_ptr(),
key_size,
)
};
if rc != 0 {
return Err(rc);
}
let wc_blake2b = unsafe { wc_blake2b.assume_init() };
let blake2b = BLAKE2b { wc_blake2b };
Ok(blake2b)
}
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
let data_size = data.len() as u32;
let rc = unsafe { sys::wc_Blake2bUpdate(&mut self.wc_blake2b, data.as_ptr(), data_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
let hash_size = hash.len() as u32;
let rc =
unsafe { sys::wc_Blake2bFinal(&mut self.wc_blake2b, hash.as_mut_ptr(), hash_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(blake2b_hmac)]
pub struct BLAKE2bHmac {
wc_blake2b: sys::Blake2b,
}
#[cfg(blake2b_hmac)]
impl BLAKE2bHmac {
pub const DIGEST_SIZE: usize = sys::WC_BLAKE2B_DIGEST_SIZE as usize;
pub fn new(key: &[u8]) -> Result<Self, i32> {
let mut wc_blake2b: MaybeUninit<sys::Blake2b> = MaybeUninit::uninit();
let rc =
unsafe { sys::wc_Blake2bHmacInit(wc_blake2b.as_mut_ptr(), key.as_ptr(), key.len()) };
if rc != 0 {
return Err(rc);
}
let wc_blake2b = unsafe { wc_blake2b.assume_init() };
let hmac_blake2b = BLAKE2bHmac { wc_blake2b };
Ok(hmac_blake2b)
}
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
let rc =
unsafe { sys::wc_Blake2bHmacUpdate(&mut self.wc_blake2b, data.as_ptr(), data.len()) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn finalize(&mut self, key: &[u8], mac: &mut [u8; Self::DIGEST_SIZE]) -> Result<(), i32> {
let rc = unsafe {
sys::wc_Blake2bHmacFinal(
&mut self.wc_blake2b,
key.as_ptr(),
key.len(),
mac.as_mut_ptr(),
mac.len(),
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn hmac(data: &[u8], key: &[u8], out: &mut [u8; Self::DIGEST_SIZE]) -> Result<(), i32> {
let rc = unsafe {
sys::wc_Blake2bHmac(
data.as_ptr(),
data.len(),
key.as_ptr(),
key.len(),
out.as_mut_ptr(),
out.len(),
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(blake2s)]
pub struct BLAKE2s {
wc_blake2s: sys::Blake2s,
}
#[cfg(blake2s)]
impl BLAKE2s {
pub fn new(digest_size: usize) -> Result<Self, i32> {
let digest_size = digest_size as u32;
let mut wc_blake2s: MaybeUninit<sys::Blake2s> = MaybeUninit::uninit();
let rc = unsafe { sys::wc_InitBlake2s(wc_blake2s.as_mut_ptr(), digest_size) };
if rc != 0 {
return Err(rc);
}
let wc_blake2s = unsafe { wc_blake2s.assume_init() };
let blake2s = BLAKE2s { wc_blake2s };
Ok(blake2s)
}
pub fn new_with_key(digest_size: usize, key: &[u8]) -> Result<Self, i32> {
let digest_size = digest_size as u32;
let mut wc_blake2s: MaybeUninit<sys::Blake2s> = MaybeUninit::uninit();
let key_size = key.len() as u32;
let rc = unsafe {
sys::wc_InitBlake2s_WithKey(
wc_blake2s.as_mut_ptr(),
digest_size,
key.as_ptr(),
key_size,
)
};
if rc != 0 {
return Err(rc);
}
let wc_blake2s = unsafe { wc_blake2s.assume_init() };
let blake2s = BLAKE2s { wc_blake2s };
Ok(blake2s)
}
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
let data_size = data.len() as u32;
let rc = unsafe { sys::wc_Blake2sUpdate(&mut self.wc_blake2s, data.as_ptr(), data_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> {
let hash_size = hash.len() as u32;
let rc =
unsafe { sys::wc_Blake2sFinal(&mut self.wc_blake2s, hash.as_mut_ptr(), hash_size) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
}
#[cfg(blake2s_hmac)]
pub struct BLAKE2sHmac {
wc_blake2s: sys::Blake2s,
}
#[cfg(blake2s_hmac)]
impl BLAKE2sHmac {
pub const DIGEST_SIZE: usize = sys::WC_BLAKE2S_DIGEST_SIZE as usize;
pub fn new(key: &[u8]) -> Result<Self, i32> {
let mut wc_blake2s: MaybeUninit<sys::Blake2s> = MaybeUninit::uninit();
let rc =
unsafe { sys::wc_Blake2sHmacInit(wc_blake2s.as_mut_ptr(), key.as_ptr(), key.len()) };
if rc != 0 {
return Err(rc);
}
let wc_blake2s = unsafe { wc_blake2s.assume_init() };
let hmac_blake2s = BLAKE2sHmac { wc_blake2s };
Ok(hmac_blake2s)
}
pub fn update(&mut self, data: &[u8]) -> Result<(), i32> {
let rc =
unsafe { sys::wc_Blake2sHmacUpdate(&mut self.wc_blake2s, data.as_ptr(), data.len()) };
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn finalize(&mut self, key: &[u8], mac: &mut [u8; Self::DIGEST_SIZE]) -> Result<(), i32> {
let rc = unsafe {
sys::wc_Blake2sHmacFinal(
&mut self.wc_blake2s,
key.as_ptr(),
key.len(),
mac.as_mut_ptr(),
mac.len(),
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
pub fn hmac(data: &[u8], key: &[u8], out: &mut [u8; Self::DIGEST_SIZE]) -> Result<(), i32> {
let rc = unsafe {
sys::wc_Blake2sHmac(
data.as_ptr(),
data.len(),
key.as_ptr(),
key.len(),
out.as_mut_ptr(),
out.len(),
)
};
if rc != 0 {
return Err(rc);
}
Ok(())
}
}