use super::{
DH_MODE, DH_WITH_HMAC_MODE, HMAC_MODE, KEM_CIPHERTEXT_SIZE, KEM_MODE, KEM_WITH_DH_HYBRID_MODE,
KEY_SIZE, SESSION_MODE, SESSION_WITH_KEYGEN_MODE, dh_extract, hmac_extract, kem_extract,
session_extract,
};
#[derive(Debug)]
pub enum Components {
Session(
Option<[u8; KEY_SIZE]>,
),
Hmac(
usize,
),
Dh(
[u8; KEY_SIZE],
bool,
),
Kem(
[u8; KEY_SIZE],
[u8; KEM_CIPHERTEXT_SIZE],
bool,
),
}
#[allow(clippy::missing_errors_doc)]
pub fn extract_components(
position: usize,
mut encrypted_content: Vec<u8>,
) -> anyhow::Result<(Components, Vec<u8>)> {
let mode_meta = extract_components_mut(position, &mut encrypted_content)?;
Ok((mode_meta, encrypted_content))
}
#[allow(clippy::missing_errors_doc)]
pub fn extract_components_mut(
position: usize,
encrypted_content: &mut Vec<u8>,
) -> anyhow::Result<Components> {
let mode = encrypted_content[encrypted_content.len() - 1];
Ok(match mode {
HMAC_MODE => Components::Hmac(hmac_extract(encrypted_content)?),
SESSION_MODE | SESSION_WITH_KEYGEN_MODE => Components::Session(session_extract(
encrypted_content,
mode == SESSION_WITH_KEYGEN_MODE,
)?),
DH_MODE | DH_WITH_HMAC_MODE => Components::Dh(
dh_extract(position, encrypted_content)?,
mode == DH_WITH_HMAC_MODE,
),
KEM_MODE | KEM_WITH_DH_HYBRID_MODE => {
let (content_key, ciphertext) = kem_extract(position, encrypted_content)?;
Components::Kem(content_key, ciphertext, mode == KEM_WITH_DH_HYBRID_MODE)
}
_ => unimplemented!(),
})
}