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

camellia_cipher.rs (5959B)

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