myph-v2.git


myph-v2

~ rust shellcode loader with evasive capabilities
git clone https://github.com/djnnvx/myph-v2.git
log | files | refs | archive | README

aes_cipher.rs (6056B)

      1 use super::Encryptor;
      2 use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyIvInit};
      3 use aes::Aes128;
      4 use rand::Rng;
      5 use sha2::{Digest, Sha256};
      6 
      7 type Aes128CbcEnc = cbc::Encryptor<Aes128>;
      8 #[allow(dead_code)]
      9 type Aes128CbcDec = cbc::Decryptor<Aes128>;
     10 
     11 /// AES-128 cipher implementation with CBC mode
     12 pub struct AesEncryptor {
     13     key: [u8; 16],
     14 }
     15 
     16 impl AesEncryptor {
     17     /// Creates a new AES encryptor with the given key
     18     /// Uses SHA-256 to derive a proper 16-byte key from the input
     19     pub fn new(key: &str) -> Self {
     20         let mut hasher = Sha256::new();
     21         hasher.update(key.as_bytes());
     22         let hash = hasher.finalize();
     23 
     24         // Take first 16 bytes of hash for AES-128
     25         let mut key_bytes = [0u8; 16];
     26         key_bytes.copy_from_slice(&hash[..16]);
     27 
     28         println!(
     29             "[AES] Derived key from input (SHA-256): {:02x?}",
     30             &key_bytes[..8]
     31         );
     32 
     33         Self { key: key_bytes }
     34     }
     35 }
     36 
     37 impl Encryptor for AesEncryptor {
     38     fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> {
     39         // Generate random IV
     40         let mut rng = rand::thread_rng();
     41         let mut iv = [0u8; 16];
     42         rng.fill(&mut iv);
     43 
     44         println!(
     45             "[AES] Generated random IV for encryption: {:02x?}",
     46             &iv[..8]
     47         );
     48 
     49         let cipher = Aes128CbcEnc::new(&self.key.into(), &iv.into());
     50         let ciphertext = cipher.encrypt_padded_vec_mut::<Pkcs7>(data);
     51 
     52         // Prepend IV to ciphertext
     53         let mut result = iv.to_vec();
     54         result.extend_from_slice(&ciphertext);
     55 
     56         Ok(result)
     57     }
     58 
     59     fn decrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> {
     60         if data.len() < 16 {
     61             return Err("Ciphertext too short to contain IV".to_string());
     62         }
     63 
     64         // Extract IV from beginning of data
     65         let iv: [u8; 16] = data[..16].try_into().unwrap();
     66         let ciphertext = &data[16..];
     67 
     68         println!("[AES] Extracted IV for decryption: {:02x?}", &iv[..8]);
     69 
     70         let cipher = Aes128CbcDec::new(&self.key.into(), &iv.into());
     71         cipher
     72             .decrypt_padded_vec_mut::<Pkcs7>(ciphertext)
     73             .map_err(|e| format!("Decryption error: {:?}", e))
     74     }
     75 
     76     fn key_size(&self) -> usize {
     77         16 // AES-128 uses 16-byte keys
     78     }
     79 
     80     fn algorithm_name(&self) -> &'static str {
     81         "AES-128-CBC"
     82     }
     83 
     84     fn uses_iv(&self) -> bool {
     85         true
     86     }
     87 
     88     fn generate_decrypt_code(&self) -> &'static str {
     89         r#"/// Decrypts AES-128 CBC encrypted data using the provided key
     90 ///
     91 /// Returns `Ok(Vec<u8>)` with decrypted data if successful, otherwise returns an error.
     92 pub fn decrypt_aes(data: &[u8], key: &[u8]) -> Result<Vec<u8>, String> {
     93     use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, KeyIvInit};
     94     use aes::Aes128;
     95     
     96     if data.len() < 16 {
     97         return Err("Ciphertext too short to contain IV".to_string());
     98     }
     99     
    100     if key.len() != 16 {
    101         return Err("Key must be 16 bytes for AES-128".to_string());
    102     }
    103     
    104     let iv: [u8; 16] = data[..16].try_into().unwrap();
    105     let ciphertext = &data[16..];
    106     
    107     let key_array: [u8; 16] = key.try_into().map_err(|_| "Invalid key length".to_string())?;
    108     
    109     type Aes128CbcDec = cbc::Decryptor<Aes128>;
    110     let cipher = Aes128CbcDec::new(&key_array.into(), &iv.into());
    111     cipher
    112         .decrypt_padded_vec_mut::<Pkcs7>(ciphertext)
    113         .map_err(|e| format!("Decryption error: {:?}", e))
    114 }"#
    115     }
    116 
    117     fn required_dependencies(&self) -> Vec<(&'static str, &'static str)> {
    118         vec![("aes", "0.8"), ("cbc", "0.1")]
    119     }
    120 }
    121 
    122 #[cfg(test)]
    123 mod tests {
    124     use super::*;
    125 
    126     #[test]
    127     fn test_aes_encrypt_decrypt() {
    128         let encryptor = AesEncryptor::new("my-secret-key-123");
    129         let plaintext = b"Hello, World!";
    130 
    131         let encrypted = encryptor.encrypt(plaintext).unwrap();
    132         assert_ne!(encrypted, plaintext);
    133 
    134         let decrypted = encryptor.decrypt(&encrypted).unwrap();
    135         assert_eq!(decrypted, plaintext);
    136     }
    137 
    138     #[test]
    139     fn test_aes_different_keys() {
    140         let encryptor1 = AesEncryptor::new("key1");
    141         let encryptor2 = AesEncryptor::new("key2");
    142         let plaintext = b"Test data";
    143 
    144         let encrypted1 = encryptor1.encrypt(plaintext).unwrap();
    145         let encrypted2 = encryptor2.encrypt(plaintext).unwrap();
    146 
    147         assert_ne!(encrypted1, encrypted2);
    148     }
    149 
    150     #[test]
    151     fn test_aes_empty_data() {
    152         let encryptor = AesEncryptor::new("key");
    153         let empty: &[u8] = &[];
    154 
    155         let encrypted = encryptor.encrypt(empty).unwrap();
    156         // AES with padding will have at least one block
    157         assert!(encrypted.len() >= 16);
    158 
    159         let decrypted = encryptor.decrypt(&encrypted).unwrap();
    160         assert_eq!(decrypted.len(), 0);
    161     }
    162 
    163     #[test]
    164     fn test_aes_wrong_key_decryption() {
    165         let encryptor1 = AesEncryptor::new("correct-key");
    166         let encryptor2 = AesEncryptor::new("wrong-key");
    167         let plaintext = b"Secret message";
    168 
    169         let encrypted = encryptor1.encrypt(plaintext).unwrap();
    170         let result = encryptor2.decrypt(&encrypted);
    171 
    172         // Decryption with wrong key should fail or produce garbage
    173         assert!(result.is_err() || result.unwrap() != plaintext);
    174     }
    175 
    176     #[test]
    177     fn test_aes_long_data() {
    178         let encryptor = AesEncryptor::new("secret-key");
    179         let plaintext =
    180             b"This is a much longer message that exceeds the AES block size of 16 bytes";
    181 
    182         let encrypted = encryptor.encrypt(plaintext).unwrap();
    183         assert_ne!(encrypted, plaintext);
    184 
    185         let decrypted = encryptor.decrypt(&encrypted).unwrap();
    186         assert_eq!(decrypted, plaintext);
    187     }
    188 
    189     #[test]
    190     fn test_aes_binary_data() {
    191         let encryptor = AesEncryptor::new("key");
    192         let plaintext: Vec<u8> = (0..=255).collect();
    193 
    194         let encrypted = encryptor.encrypt(&plaintext).unwrap();
    195         assert_ne!(encrypted, plaintext);
    196 
    197         let decrypted = encryptor.decrypt(&encrypted).unwrap();
    198         assert_eq!(decrypted, plaintext);
    199     }
    200 }