use crate::{raw, Cipheriv, Decipheriv, Hash, Hmac};
pub fn hmac(
alg: &str,
key: impl AsRef<[u8]>,
infos: &[impl AsRef<[u8]>],
) -> Result<Vec<u8>, raw::CryptoErrno> {
let mut hash = Hmac::create(alg, key)?;
for info in infos {
hash.update(info)?;
}
hash.digest()
}
pub fn hash(alg: &str, infos: &[impl AsRef<[u8]>]) -> Result<Vec<u8>, raw::CryptoErrno> {
let mut hash = Hash::create(alg)?;
for info in infos {
hash.update(info)?;
}
hash.digest()
}
pub fn decrypt(
alg: &str,
key: impl AsRef<[u8]>,
iv: impl AsRef<[u8]>,
aad: impl AsRef<[u8]>,
auth_tag: impl AsRef<[u8]>,
msg: impl AsRef<[u8]>,
) -> Result<Vec<u8>, raw::CryptoErrno> {
let mut c = Decipheriv::create(alg, key, iv)?;
c.set_aad(aad)?;
c.set_auth_tag(auth_tag)?;
c.decrypt(msg)
}
pub fn encrypt(
alg: &str,
key: impl AsRef<[u8]>,
iv: impl AsRef<[u8]>,
aad: impl AsRef<[u8]>,
msg: impl AsRef<[u8]>,
) -> Result<(Vec<u8>, Vec<u8>), raw::CryptoErrno> {
let mut c = Cipheriv::create(alg, key, iv)?;
c.set_aad(aad)?;
let out = c.encrypt(msg)?;
let tag = c.take_auth_tag()?;
Ok((out, tag))
}
pub fn u8array_to_hex(arr: impl AsRef<[u8]>) -> String {
arr.as_ref()
.iter()
.map(|v| format!("{:02x}", v))
.collect::<Vec<_>>()
.join("")
}
pub fn hex_to_u8array(arr: &str) -> Option<Vec<u8>> {
if arr.len() % 2 != 0 || arr.chars().any(|v| !v.is_ascii_hexdigit()) {
return None;
}
fn hex_byte_to_u8(h: u8) -> u8 {
match h {
b'0'..=b'9' => h - b'0',
b'a'..=b'f' => 10 + h - b'a',
b'A'..=b'F' => 10 + h - b'A',
_ => unreachable!(),
}
}
Some(
arr.as_bytes()
.chunks(2)
.map(|v| (hex_byte_to_u8(v[0]) << 4) + hex_byte_to_u8(v[1]))
.collect(),
)
}