use super::error::{self, Error};
use super::{ensure_init, ffi};
pub(crate) fn derive_key_into(
out: &mut [u8],
master_key: &[u8],
context: &[u8],
) -> Result<(), Error> {
ensure_init();
debug_assert_eq!(out.len(), master_key.len());
let max_context_len = match out.len() {
16 => 120,
32 => 72,
_ => return Err(Error::InvalidArgument("key length must be 16 or 32 bytes")),
};
if context.len() > max_context_len {
return Err(Error::InvalidArgument("context too long"));
}
let context_ptr = if context.is_empty() {
core::ptr::null()
} else {
context.as_ptr()
};
let ret = unsafe {
ffi::aegis_raf_derive_master_key(
out.as_mut_ptr(),
out.len(),
master_key.as_ptr(),
master_key.len(),
context_ptr,
context.len(),
)
};
if ret != 0 {
return Err(error::map_errno_derive());
}
Ok(())
}
pub fn derive_key<const KEY_LEN: usize>(
master_key: &[u8; KEY_LEN],
context: &[u8],
) -> Result<[u8; KEY_LEN], Error> {
let mut out = [0u8; KEY_LEN];
derive_key_into(&mut out, master_key, context)?;
Ok(out)
}