1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//use super::*;
//use crypt_guard_proc::{*, log_activity, write_log};
use crate::{
*,
cryptography::{*, hmac_sign::{Sign, SignType, Operation}},
error::{*},
core::{
// removed unused KyberKeyFunctions per clippy
KeyControlVariant,
},
};
use std::result::Result;
use aes::{Aes256, cipher::KeyInit, cipher::generic_array::GenericArray};
use xts_mode::{Xts128, get_tweak_default};
/// The main struct for handling cryptographic operations with ChaCha20 algorithm.
/// It encapsulates the cryptographic information and shared secret required for encryption and decryption.
impl CipherAesXts {
/// Constructs a new CipherChaCha instance with specified cryptographic information.
///
/// # Parameters
/// - infos: Cryptographic information including content, passphrase, metadata, and location for encryption or decryption.
///
/// # Returns
/// A new CipherChaCha instance.
pub fn new(infos: CryptographicInformation) -> Self {
// println!("infos: {:?}", infos);
CipherAesXts { infos, sharedsecret: Vec::new() }
}
/// Retrieves the encrypted or decrypted data stored within the CryptographicInformation.
///
/// # Returns
/// A result containing the data as a vector of bytes (Vec<u8>) or a CryptError.
pub fn get_data(&self) -> Result<Vec<u8>, CryptError> {
let data = &self.infos.content()?;
let data = data.to_vec();
Ok(data)
}
/// Sets the shared secret for the cryptographic operation.
///
/// # Parameters
/// - sharedsecret: A vector of bytes (Vec<u8>) representing the shared secret.
///
/// # Returns
/// A reference to the CipherChaCha instance to allow method chaining.
pub fn set_shared_secret(&mut self, sharedsecret: Vec<u8>) -> &Self {
self.sharedsecret = sharedsecret;
self
}
/// Retrieves the shared secret.
///
/// # Returns
/// A result containing a slice of the shared secret (&[u8]) or a CryptError.
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)/*.map_err(|e| CryptError::new(e.to_string().as_str()))?*/;
//println!("decrypted: {:?}", &decrypted);
let mut hmac = Sign::new(buffer.to_vec(), passphrase, Operation::Verify, SignType::Sha512);
let data = hmac.hmac();
//println!("Verified: {:?}", &data);
Ok(data)
}
}
impl CryptographicFunctions for CipherAesXts {
/// Encrypts the provided data using the public key.
///
/// # Parameters
/// - public_key: The public key used for encryption.
///
/// # Returns
/// A result containing a tuple of the encrypted data (Vec<u8>) and the key used, or a CryptError.
fn encrypt(&mut self, public_key: Vec<u8>) -> Result<(Vec<u8>, Vec<u8>), CryptError> {
let key = KeyControlVariant::new(self.infos.metadata.key_type()?);
// Generate the first shared secret and ciphertext
let (sharedsecret1, ciphertext1) = key.encap(&public_key)?;
// Generate the second shared secret and ciphertext
let (sharedsecret2, ciphertext2) = key.encap(&public_key)?;
// Concatenate both shared secrets and ciphertexts
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))
}
/// Decrypts the provided data using the secret key and ciphertext.
///
/// # Parameters
/// - secret_key: The secret key used for decryption.
/// - ciphertext: The ciphertext to decrypt.
///
/// # Returns
/// A result containing the decrypted data (Vec<u8>), or a CryptError.
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)
}
}