use crate::utils::*;
use botan_sys::*;
#[must_use]
pub fn const_time_compare<T: Copy>(a: &[T], b: &[T]) -> bool {
if a.len() != b.len() {
return false;
}
let bytes = mem::size_of::<T>() * a.len();
let rc = unsafe {
botan_constant_time_compare(a.as_ptr() as *const u8, b.as_ptr() as *const u8, bytes)
};
rc == 0
}
pub fn scrub_mem<T: Copy>(a: &mut [T]) {
let bytes = mem::size_of::<T>() * a.len();
unsafe { botan_scrub_mem(a.as_mut_ptr() as *mut c_void, bytes) };
}
pub fn hex_encode(x: &[u8]) -> Result<String> {
let flags = 0u32;
let mut output = vec![0u8; x.len() * 2];
botan_call!(
botan_hex_encode,
x.as_ptr(),
x.len(),
output.as_mut_ptr() as *mut c_char,
flags
)?;
String::from_utf8(output).map_err(Error::conversion_error)
}
pub fn hex_decode(x: &str) -> Result<Vec<u8>> {
let mut output = vec![0u8; x.len() / 2];
let mut output_len = output.len();
let input = make_cstr(x)?;
botan_call!(
botan_hex_decode,
input.as_ptr(),
x.len(),
output.as_mut_ptr(),
&mut output_len
)?;
output.resize(output_len, 0);
Ok(output)
}
pub fn base64_encode(x: &[u8]) -> Result<String> {
let b64_len = 1 + ((x.len() + 2) / 3) * 4;
call_botan_ffi_returning_string(b64_len, &|out_buf, out_len| unsafe {
botan_base64_encode(x.as_ptr(), x.len(), out_buf as *mut c_char, out_len)
})
}
pub fn base64_decode(x: &str) -> Result<Vec<u8>> {
let bin_len = x.len();
let input = make_cstr(x)?;
call_botan_ffi_returning_vec_u8(bin_len, &|out_buf, out_len| unsafe {
botan_base64_decode(input.as_ptr(), x.len(), out_buf, out_len)
})
}