use core::mem::MaybeUninit;
pub(crate) struct Sha512Context {
ctx: aws_lc_sys::SHA512_CTX,
}
impl Sha512Context {
pub(crate) fn new() -> Self {
let mut ctx = MaybeUninit::uninit();
unsafe {
aws_lc_sys::SHA512_Init(ctx.as_mut_ptr());
Self {
ctx: ctx.assume_init(),
}
}
}
pub(crate) fn update(&mut self, data: &[u8]) {
unsafe {
aws_lc_sys::SHA512_Update(
&mut self.ctx,
data.as_ptr().cast::<core::ffi::c_void>(),
data.len(),
);
}
}
pub(crate) fn finish(mut self) -> [u8; 64] {
let mut result = [0u8; 64];
unsafe {
aws_lc_sys::SHA512_Final(result.as_mut_ptr(), &mut self.ctx);
}
result
}
}
impl Drop for Sha512Context {
fn drop(&mut self) {
unsafe {
aws_lc_sys::OPENSSL_cleanse(
(&mut self.ctx as *mut aws_lc_sys::SHA512_CTX).cast::<core::ffi::c_void>(),
core::mem::size_of::<aws_lc_sys::SHA512_CTX>(),
);
}
}
}
pub(crate) fn constant_time_eq(a: &[u8], b: &[u8]) -> bool {
if a.len() != b.len() {
return false;
}
unsafe {
aws_lc_sys::CRYPTO_memcmp(
a.as_ptr().cast::<core::ffi::c_void>(),
b.as_ptr().cast::<core::ffi::c_void>(),
a.len(),
) == 0
}
}
pub(crate) fn random_bytes(buf: &mut [u8]) {
unsafe {
aws_lc_sys::RAND_bytes(buf.as_mut_ptr(), buf.len());
}
}
pub(crate) fn secure_zero_bytes(data: &mut [u8]) {
if !data.is_empty() {
unsafe {
aws_lc_sys::OPENSSL_cleanse(data.as_mut_ptr().cast::<core::ffi::c_void>(), data.len());
}
}
}