use aead::{AeadCore, Key};
use digest::KeyInit;
use zerocopy::IntoBytes;
use crate::{
FloeAead, FloeKdf,
types::{FloeIv, Parameters, Segment},
};
pub(crate) fn plaintext_size<A, const S: u32>() -> usize
where
A: AeadCore,
{
#[allow(clippy::expect_used)]
(TryInto::<usize>::try_into(S).expect("The encrypted segment size should fit into a u32"))
.checked_sub(Segment::<'static, A>::overhead())
.expect("The encrypted segment size should be bigger than the segment overhead")
}
pub(crate) fn check_segment_size<A, const S: u32>()
where
A: AeadCore,
{
#[allow(clippy::panic)]
if S > u32::MAX - (Segment::<A>::overhead() as u32) {
panic!("Segment size is too large, the length of the segment doesn't fit into a u32");
} else if TryInto::<usize>::try_into(S).is_err() {
panic!("Segment size is too large, the length of the segment doesn't fit into a usize");
} else if S < ((Segment::<A>::overhead()) as u32) {
panic!(
"Segment size is too small, the segment doesn't have enough space for the segment header"
);
}
}
pub(crate) fn floe_kdf<A, K, const N: usize, const S: u32>(
key: &Key<A>,
floe_iv: &FloeIv<N>,
associated_data: &[u8],
purpose: &[u8],
) -> digest::CtOutput<K>
where
A: FloeAead,
K: FloeKdf,
{
let params = Parameters::new::<A, K, N, S>();
#[allow(clippy::expect_used)]
<K as KeyInit>::new_from_slice(key)
.expect(
"the KDF input key material should be big enough as this is determined by AEAD_KEY_LEN",
)
.chain_update(params.as_bytes())
.chain_update(floe_iv.as_array())
.chain_update(purpose)
.chain_update(associated_data)
.chain_update([1])
.finalize()
}