1use crate::utils::*;
2use botan_sys::*;
3
4#[must_use]
8pub fn const_time_compare<T: Copy>(a: &[T], b: &[T]) -> bool {
9 if a.len() != b.len() {
10 return false;
11 }
12
13 let bytes = mem::size_of_val(a);
14 let rc = unsafe {
15 botan_constant_time_compare(a.as_ptr() as *const u8, b.as_ptr() as *const u8, bytes)
16 };
17
18 rc == 0
19}
20
21pub fn scrub_mem<T: Copy>(a: &mut [T]) {
26 let bytes = mem::size_of_val(a);
27 unsafe { botan_scrub_mem(a.as_mut_ptr() as *mut c_void, bytes) };
28}
29
30pub fn hex_encode(x: &[u8]) -> Result<String> {
32 let flags = 0u32;
33
34 let mut output = vec![0u8; x.len() * 2];
35 botan_call!(
36 botan_hex_encode,
37 x.as_ptr(),
38 x.len(),
39 output.as_mut_ptr() as *mut c_char,
40 flags
41 )?;
42
43 String::from_utf8(output).map_err(Error::conversion_error)
44}
45
46pub fn hex_decode(x: &str) -> Result<Vec<u8>> {
48 let mut output = vec![0u8; x.len() / 2];
49 let mut output_len = output.len();
50
51 let input = make_cstr(x)?;
52
53 botan_call!(
54 botan_hex_decode,
55 input.as_ptr(),
56 x.len(),
57 output.as_mut_ptr(),
58 &mut output_len
59 )?;
60
61 output.resize(output_len, 0);
62
63 Ok(output)
64}
65
66pub fn base64_encode(x: &[u8]) -> Result<String> {
75 let b64_len = 1 + ((x.len() + 2) / 3) * 4;
76
77 call_botan_ffi_returning_string(b64_len, &|out_buf, out_len| unsafe {
78 botan_base64_encode(x.as_ptr(), x.len(), out_buf as *mut c_char, out_len)
79 })
80}
81
82pub fn base64_decode(x: &str) -> Result<Vec<u8>> {
91 let bin_len = x.len();
94
95 let input = make_cstr(x)?;
96
97 call_botan_ffi_returning_vec_u8(bin_len, &|out_buf, out_len| unsafe {
98 botan_base64_decode(input.as_ptr(), x.len(), out_buf, out_len)
99 })
100}