use crate::r5_hash::hash;
use openssl::symm::{Cipher, Mode, Crypter};
pub fn round5_dem(c2: &mut [u8], key: &[u8], m: &[u8]) {
let mut final_key_iv = [0u8; 48];
let mut tag = [0u8; 16];
let mut c2_length: usize = 0;
hash(&mut final_key_iv, &key, key.len() as u8);
let cipher = match key.len() {
16 => Cipher::aes_128_gcm(),
24 => Cipher::aes_192_gcm(),
32 => Cipher::aes_256_gcm(),
_ => panic!()
};
let mut crypter = Crypter::new(
cipher, Mode::Encrypt,
&final_key_iv[..key.len()],
Some(&final_key_iv[key.len()..key.len() + cipher.iv_len().unwrap()])
).unwrap();
crypter.pad(false);
c2_length += crypter.update(m, c2).unwrap();
c2_length += crypter.finalize(&mut c2[c2_length..]).unwrap();
crypter.get_tag(&mut tag).unwrap();
c2[c2_length..].copy_from_slice(&tag);
}
pub fn round5_dem_inverse(key: &[u8], c2: &[u8]) -> Vec<u8> {
let mut final_key_iv = [0u8; 48];
let mut m_length: usize = 0;
let c2_len_no_tag = c2.len() - 16;
hash(&mut final_key_iv, &key, key.len() as u8);
let tag = &c2[c2_len_no_tag..].to_vec();
let cipher = match key.len() {
16 => Cipher::aes_128_gcm(),
24 => Cipher::aes_192_gcm(),
32 => Cipher::aes_256_gcm(),
_ => panic!()
};
let mut decrypter = Crypter::new(
cipher, Mode::Decrypt,
&final_key_iv[..key.len()],
Some(&final_key_iv[key.len()..key.len() + cipher.iv_len().unwrap()])
).unwrap();
let mut output = vec![0u8; c2_len_no_tag + cipher.block_size()];
decrypter.pad(false);
m_length += decrypter.update(&c2[..c2_len_no_tag], &mut output).unwrap();
decrypter.set_tag(tag).unwrap();
m_length += decrypter.finalize(&mut output[m_length..]).unwrap();
output.truncate(m_length);
output
}