use std::mem::MaybeUninit;
use std::os::raw::c_char;
use gmssl_rs_sys;
#[derive(Debug)]
pub struct Sm3 {
ctx: MaybeUninit<gmssl_rs_sys::SM3_CTX>,
}
impl Sm3 {
pub fn new() -> Self {
let mut ctx = MaybeUninit::uninit();
unsafe {
gmssl_rs_sys::sm3_init(ctx.as_mut_ptr());
}
Sm3 { ctx }
}
pub fn update(&mut self, data: &[u8]) {
unsafe {
gmssl_rs_sys::sm3_update(self.ctx.as_mut_ptr(), data.as_ptr(), data.len());
}
}
pub fn finish(&mut self) -> [u8; gmssl_rs_sys::SM3_DIGEST_SIZE] {
let mut dgst = [0u8; gmssl_rs_sys::SM3_DIGEST_SIZE];
unsafe {
gmssl_rs_sys::sm3_finish(self.ctx.as_mut_ptr(), dgst.as_mut_ptr());
}
dgst
}
pub fn digest(data: &[u8]) -> [u8; gmssl_rs_sys::SM3_DIGEST_SIZE] {
let mut sm3 = Sm3::new();
sm3.update(data);
sm3.finish()
}
pub fn reset(&mut self) {
unsafe {
gmssl_rs_sys::sm3_init(self.ctx.as_mut_ptr());
}
}
}
impl Default for Sm3 {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug)]
pub struct Sm3Hmac {
ctx: MaybeUninit<gmssl_rs_sys::SM3_HMAC_CTX>,
}
impl Sm3Hmac {
pub fn new(key: &[u8]) -> Self {
let mut ctx = MaybeUninit::uninit();
unsafe {
gmssl_rs_sys::sm3_hmac_init(ctx.as_mut_ptr(), key.as_ptr(), key.len());
}
Sm3Hmac { ctx }
}
pub fn update(&mut self, data: &[u8]) {
unsafe {
gmssl_rs_sys::sm3_hmac_update(self.ctx.as_mut_ptr(), data.as_ptr(), data.len());
}
}
pub fn finish(&mut self) -> [u8; gmssl_rs_sys::SM3_HMAC_SIZE] {
let mut mac = [0u8; gmssl_rs_sys::SM3_HMAC_SIZE];
unsafe {
gmssl_rs_sys::sm3_hmac_finish(self.ctx.as_mut_ptr(), mac.as_mut_ptr());
}
mac
}
pub fn mac(key: &[u8], data: &[u8]) -> [u8; gmssl_rs_sys::SM3_HMAC_SIZE] {
let mut hmac = Sm3Hmac::new(key);
hmac.update(data);
hmac.finish()
}
pub fn reset(&mut self, key: &[u8]) {
unsafe {
gmssl_rs_sys::sm3_hmac_init(self.ctx.as_mut_ptr(), key.as_ptr(), key.len());
}
}
}
pub fn sm3_pbkdf2(
password: &[u8],
salt: &[u8],
iterations: usize,
out: &mut [u8],
) -> Result<(), crate::error::GmsslError> {
use crate::error::ok_or_library_error;
let ret = unsafe {
gmssl_rs_sys::pbkdf2_hmac_sm3_genkey(
password.as_ptr() as *const c_char,
password.len(),
salt.as_ptr(),
salt.len(),
iterations,
out.len(),
out.as_mut_ptr(),
)
};
ok_or_library_error(ret, "pbkdf2_hmac_sm3_genkey")
}
#[cfg(test)]
mod tests;