use crate::{
core::{
KeyControlVariant,
},
cryptography::{
hmac_sign::{Operation, Sign, SignType},
*,
},
error::*,
*,
};
use aes::{cipher::generic_array::GenericArray, cipher::KeyInit, Aes256};
use std::result::Result;
use xts_mode::{get_tweak_default, Xts128};
impl CipherAesXts {
pub fn new(infos: CryptographicInformation) -> Self {
CipherAesXts {
infos,
sharedsecret: Vec::new(),
}
}
pub fn get_data(&self) -> Result<Vec<u8>, CryptError> {
let data = &self.infos.content()?;
let data = data.to_vec();
Ok(data)
}
pub fn set_shared_secret(&mut self, sharedsecret: Vec<u8>) -> &Self {
self.sharedsecret = sharedsecret;
self
}
pub fn sharedsecret(&self) -> Result<&[u8], CryptError> {
Ok(&self.sharedsecret)
}
fn encryption(&self) -> Result<Vec<u8>, CryptError> {
let plaintext = self.infos.content()?;
let passphrase = self.infos.passphrase()?.to_vec();
let cipher_1 = Aes256::new(GenericArray::from_slice(&self.sharedsecret[..32]));
let cipher_2 = Aes256::new(GenericArray::from_slice(&self.sharedsecret[32..]));
let cipher = Xts128::<Aes256>::new(cipher_1, cipher_2);
let mut hmac = Sign::new(
plaintext.to_vec(),
passphrase,
Operation::Sign,
SignType::Sha512,
);
let mut data = hmac.hmac();
let sector_size = 0x200;
let first_sector_index = 0;
cipher.encrypt_area(
&mut data,
sector_size,
first_sector_index,
get_tweak_default,
);
Ok(data)
}
fn decryption(&self) -> Result<Vec<u8>, CryptError> {
let mut buffer = self.infos.content()?.to_owned();
let passphrase = self.infos.passphrase()?.to_vec();
let cipher_1 = Aes256::new(GenericArray::from_slice(&self.sharedsecret[..32]));
let cipher_2 = Aes256::new(GenericArray::from_slice(&self.sharedsecret[32..]));
let cipher = Xts128::<Aes256>::new(cipher_1, cipher_2);
let sector_size = 0x200;
let first_sector_index = 0;
cipher.decrypt_area(&mut buffer, sector_size, first_sector_index, get_tweak_default);
let mut hmac = Sign::new(
buffer.to_vec(),
passphrase,
Operation::Verify,
SignType::Sha512,
);
let data = hmac.hmac();
Ok(data)
}
}
impl CryptographicFunctions for CipherAesXts {
fn encrypt(&mut self, public_key: Vec<u8>) -> Result<(Vec<u8>, Vec<u8>), CryptError> {
let key = KeyControlVariant::new(self.infos.metadata.key_type()?);
let (sharedsecret1, ciphertext1) = key.encap(&public_key)?;
let (sharedsecret2, ciphertext2) = key.encap(&public_key)?;
let sharedsecret = [sharedsecret1.to_owned(), sharedsecret2.to_owned()].concat();
let ciphertext = [ciphertext1.to_owned(), ciphertext2.to_owned()].concat();
let _ = self.set_shared_secret(sharedsecret);
let encrypted_data = self.encryption()?;
Ok((encrypted_data, ciphertext))
}
fn decrypt(&mut self, secret_key: Vec<u8>, ciphertext: Vec<u8>) -> Result<Vec<u8>, CryptError> {
let key = KeyControlVariant::new(self.infos.metadata.key_type()?);
let ciphertext_len = ciphertext.len() / 2;
let ciphertext1 = ciphertext[..ciphertext_len].to_vec();
let ciphertext2 = ciphertext[ciphertext_len..].to_vec();
let sharedsecret1 = key.decap(&secret_key, &ciphertext1)?;
let sharedsecret2 = key.decap(&secret_key, &ciphertext2)?;
let sharedsecret = [sharedsecret1.to_owned(), sharedsecret2.to_owned()].concat();
let _ = self.set_shared_secret(sharedsecret);
let decrypted_data = self.decryption()?;
Ok(decrypted_data)
}
}